K8S和Docker的关系
K8S和Docker的关系
原文网址:K8S和Docker的关系_IT利刃出鞘的博客-CSDN博客
简介
说明
本文介绍K8S,包括:K8S和Docker的关系、不同的部署方式之间的区别。
官网
Github:https://github.com/kubernetes/kubernetes
K8S和Docker的关系
Docker
Docker是用于构建、分发、运行容器的平台和工具。
K8S
K8S是一个使用 Docker 容器进行编排的系统,主要围绕 pods 进行工作。 Pods 是 k8s 生态中最小的调度单位,可以包含一个或多个容器。
K8S使用Docker进行编排,也可以使用其他容器管理工具,例如:RunC、Containerted 等。
K8S解决了裸跑 Docker 的若干痛点:
- 单机使用,无法有效集群
- 随着容器数量的上升,管理成本攀升
- 没有有效的容灾、自愈机制
- 没有预设编排模板,无法实现快速、大规模容器调度
- 若要启动一些“软件”,只能一个个去启动(docker run ..)。
- 没有统一的配置管理中心工具
- 没有容器生命周期的管理工具
- 没有图形化运维管理工具
部署方式的对比
说明
应用有如下几种部署方式:
- 传统方式
- 手动安装MySQL、Nginx,运行应用等
- 缺点:麻烦
- docker
- 安装过程只需要拉取镜像,启动即可,而不用关心软件的配置,版本等信息。
- 缺点:
- 如果容器很多,工作量依然很大;
- 真实的业务场景下,容器应用间的依赖关系,网络通信,数据持久化,状态等非常复杂,用这种方式处理起来非常棘手。
- docker-compose
- 只能单机编排容器,不能实现多机编排。可以认为是一个单机版“操作系统”
- Docker swarm
- 支持分布式下环境下的容器编排
- 缺点:
- 只有分布式编排这一个功能,没有动态伸缩、可视化等功能
- K8S
- 支持分布式下环境下的容器编排
- 优点:
- 功能很多。
示例
我们看一个简单的场景,来理解为什么编排能力才是我们更看重的东西。
我们以部署一个wordpress博客网站进行示例。
方式1:最传统的方式
你需要安装配置mysql, 安装nginx服务器,以及wordpress程序等等…
仅仅部署几个应用,你就能觉得它的复杂,配置的繁琐。可以想象,如果是几十上百个应用,自动化的过程不可避免。
方式2:独立的Docker容器
-
#1.拉取镜像
-
docker pull mysql
-
docker pull wordpress
-
#2.启动mysql
-
docker run --name w-mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql
-
#3.启动wordpress,并连接mysql
-
docker run --name w-wordpress --
link w-mysql:db -p 80:80 -d wordpress:latest
可以看到,安装过程只需要拉取镜像,启动即可,而不用关心软件的配置,版本等信息。简化了不少,但是还是手动去启动,拉取镜像等,如果容器很多,工作量依然很大,这只是个博客系统比较简单,真实的业务场景下,容器应用间的依赖关系,网络通信,数据持久化,状态等等我们关心的问题非常复杂,用这种方式处理起来非常棘手。
方式3:docker-compose 轻量编排
示例
定义一个docker-compose-wordpress.yml
-
version:
'3.3'
-
services:
-
db:
-
image: mysql:
5.7
-
container_name: mysql
-
security_opt:
-
- seccomp:unconfined
-
ports:
-
-
3306:
3306
-
volumes:
-
-
/opt
/module
/mysql
/conf:
/etc
/mysql
/conf.d
-
-
/opt
/module
/mysql
/
data:
/var
/lib
/mysql
-
-
/opt
/module
/mysql
/logs:
/var
/log
/mysql
-
re
start: always
-
environment:
-
MYSQL_ROOT_PASSWORD:
123456
-
MYSQL_DATABASE: wordpress
-
wordpress:
-
depends_
on:
-
- db
-
image: wordpress:latest
-
ports:
-
-
"80:80"
-
re
start: always
-
environment:
-
WORDPRESS_DB_HOST: db:
3306
-
WORDPRESS_DB_USER: root
-
WORDPRESS_DB_PASSWORD:
123456
-
WORDPRESS_DB_NAME: wordpress
这里的配置文件虽然看着很多,其实它的层次很清楚。services我们可以认为是一组应用,是一种抽象,具体到这里可以认为是博客服务。
博客服务需要mysql和wordpress两个容器配合,所以紧接着db(名称可以自定义)指的就是mysql,在后边则描述了对应的镜像,端口等信息。
而wordpress,有一个关键字depends_on,则描述了它和db的依赖关系。通过这样一个描述文件。
这样一个文件,用的语法就是yaml文件的语法,相信开发过java微服务的肯定很熟悉,我们的配置文件大多都是用这种方式配置。
然后我们只需要执行如下命令,即可启动对应的容器,并且相互关联:
-
#docker-compose指令
-
docker-compose -f docker-compose-wordpress.yml up -d
此时查看容器运行情况:
-
[root@VM_
0_
13_centos module]# docker-compose ps
-
Name Command State Ports
-
-----------------------------------------------------------------------------------------------
-
module_wordpress_
1 docker-entrypoint.sh apach ...
Up
0.0.0.0:
80-
>
80
/tcp
-
mysql docker-entrypoint.sh mysqld
Up
0.0.0.0:
3306-
>
3306
/tcp,
33060
/tcp
或者直接用docker命令查看:
-
[root@VM_
0_
13_centos module]# docker ps
-
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
-
64153ac
017a
3 wordpress:latest
"docker-entrypoint..."
3 weeks ago
Up
3 weeks
0.0.0.0:
80-
>
80
/tcp module_wordpress_
1
-
fde105
317ddd mysql:
5.7
"docker-entrypoint..."
3 weeks ago
Up
7 days
0.0.0.0:
3306-
>
3306
/tcp,
33060
/tcp mysql
可以看到docker-compose其实为我们做了三件事
- 根据yaml定义去拉取相关镜像文件(如果本地没有)
- 启动相关容器
- 建立容器关联关系:这里就是连接mysql
从上边这个例子,我们可以看到,面对复杂的容器运维工作,你只需要告诉编排工具你需要什么(定义yaml)其他的工作就交给等编排工具去做就行。当然部署一个wordpress这样一个轻量级的应用,用docker或者docker-compose就完全够用,如果用k8s去做,又是怎样一番场景,我们继续往下看。
方式4:K8S
从前面的例子,我们看到docker-compose其实就是在以容器为基本单位,帮我们部署应用。但在K8S里,编排调度的最小单位并不是容器,而是Pod。有了Docker容器,为什么还需要一个Pod? 前面我们说Docker容器就好比云计算操作系统中的应用,K8S相当于操作系统,那Pod就是进程组:即Pod是对一组容器(一个或多个)的抽象。之所以做这样一层抽象,是因为在 Borg 项目的开发和实践过程中,Google 公司的工程师们发现,他们部署的应用,往往都存在着类似于“进程和进程组”的关系。在同一个Pod中,可以直接通过localhost通信,并且可以共享网络栈和Volume。
如果用Pod描述上面的博客应用,yaml如下:
-
apiVersion: v
1
-
kind: Pod
-
metadata:
-
name: wordpress
-
name
space: blog
-
spec:
-
containers:
-
- name: wordpress
-
image: wordpress
-
ports:
-
- containerPort:
80
-
name: wdport
-
env:
-
- name: WORDPRESS_DB_HOST
-
value: localhost:
3306
-
- name: WORDPRESS_DB_USER
-
value: root
-
- name: WORDPRESS_DB_PASSWORD
-
value: root@
123
-
- name: mysql
-
image: mysql:
5.7
-
imagePullPolicy: IfNotPresent
-
args: # 新版本镜像有更新,需要使用下面的认证插件环境变量配置才会生效
-
- --
default_authentication_plugin
=mysql_
native_password
-
- --character-set-server
=utf
8mb
4
-
- --collation-server
=utf
8mb
4_unicode_ci
-
ports:
-
- containerPort:
3306
-
name: dbport
-
env:
-
- name: MYSQL_ROOT_PASSWORD
-
value: root@
123
-
- name: MYSQL_DATABASE
-
value: wordpress
-
- name: MYSQL_USER
-
value: wordpress
-
- name: MYSQL_PASSWORD
-
value: wordpress
-
volumeMounts:
-
- name: db
-
mountPath:
/var
/lib
/mysql
-
volumes:
-
- name: db
-
hostPath:
-
path:
/var
/lib
/mysql
像这样的一个 YAML 文件,对应到 Kubernetes 中,就是一个 API Object(API 对象),K8s是面向API编程,Pod是最基本的一个API对象。Pod是 Kubernetes 项目中的最小编排单位。将这个设计落实到 API 对象上,容器(Container)就成了 Pod 属性里的一个普通的字段。
这个Pod里 containers字段就是来定义容器的。volumes:定义了一个数据卷,指向了宿主机的/var/lib/mysql,而容器里则用volumeMounts字段来做关联挂载。
Deployment是更高层次的一种API对象,它可以直接控制Pod。在K8S中,这种用一种对象控制另一种对象的方式,就是控制器模式,也是面向API编程的直观体现。比如:
-
apiVersion: apps
/v
1
-
kind: Deployment
-
metadata:
-
name: nginx-deployment
-
spec:
-
selector:
-
matchLabels:
-
app: nginx
-
replicas:
2
-
template:
-
metadata:
-
labels:
-
app: nginx
-
sp
ec:
-
containers:
-
- name: nginx
-
image: nginx:
1.7.9
-
ports:
-
- containerPort:
80
这里我们定义了一个Deployment对象,它控制的Pod数量是两个,而Pod的具体属性,又通过template这个模板去生成。即描述的是一个Nginx。这样K8S通过控制循环,始终保证有两个nginx Pod实例运行。
所谓 Deployment,是一个定义多副本应用(即多个副本 Pod)的对象。Deployment 扮演的正是 Pod 的控制器的角色。这样的每一个 API 对象都有一个叫作 Metadata 的字段,这个字段就是 API 对象的“标识”,即元数据,它也是我们从 Kubernetes 里找到这个对象的主要依据。这其中最主要使用到的字段是 Labels。
像 Deployment 这样的控制器对象,就可以通过这个 Labels 字段从 Kubernetes 中过滤出它所关心的被控制对象。比如,在上面这个 YAML 文件中,Deployment 会把所有正在运行的、携带“app: nginx”标签的 Pod 识别为被管理的对象,并确保这些 Pod 的总数严格等于两个。
这个过滤规则的定义,是在 Deployment 的“spec.selector.matchLabels”字段。我们一般称之为:Label Selector。
一个 Kubernetes 的 API 对象的定义,大多可以分为 Metadata 和 Spec 两个部分。前者存放的是这个对象的元数据,对所有 API 对象来说,这一部分的字段和格式基本上是一样的;而后者存放的,则是属于这个对象独有的定义,用来描述它所要表达的功能。
更多推荐
所有评论(0)