目录
一、Deployment 控制器:概念、原理解读
1.1 Deployment 概述
1.2 Deployment 工作原理:如何管理 rs 和 Pod?
补充:什么叫做更新节奏和更新逻辑呢?
二、Deployment 资源清单文件编写技巧
三、Deployment 使用案例:创建一个 web 站点
三、Deployment 实现 pod 扩缩容
3.1 通过 deployment 管理应用,实现扩容,把副本数变成 3
3.2 通过 deployment 管理应用,实现缩容,把副本数变成 2
四、通过 k8s 实现滚动更新
4.1 滚动更新简介
4.2 在 k8s 中实现金滚动更新
测试滚动更新
Deployment 是 kubernetes 中最常用的资源对象,为 ReplicaSet 和 Pod 的创建提供了一种声明式的定义方法,在 Deployment 对象中描述一个期望的状态,Deployment 控制器就会按照一定的控制速率把实际状态改成期望状态,通过定义一个 Deployment 控制器会创建一个新的ReplicaSet 控制器,通过 ReplicaSet 创建 pod,删除 Deployment 控制器,也会删除 Deployment控制器下对应的 ReplicaSet 控制器和 pod 资源。
使用 Deployment 而不直接创建 ReplicaSet 是因为 Deployment 对象拥有许多 ReplicaSet 没有的特性,例如滚动升级、金丝雀发布、蓝绿部署和回滚。
扩展:声明式定义是指直接修改资源清单 yaml 文件,然后通过 kubectl apply -f 资源清单yaml 文件,就可以更改资源。
Deployment 控制器是建立在 rs 之上的一个控制器,可以管理多个 rs,每次更新镜像版本,都会生成一个新的 rs,把旧的 rs 替换掉,多个 rs 同时存在,但是只有一个 rs 运行。
rs v1 控制三个 pod,删除一个 pod,在 rs v2 上重新建立一个,依次类推,直到全部都是由rs v2 控制,如果rs v2有问题,还可以回滚,Deployment 是建构在rs之上的,多个 rs 组成一个Deployment,但是只有一个 rs 处于活跃状态.。
Deployment 可以使用声明式定义,直接在命令行通过纯命令的方式完成对应资源版本的内容的修改,也就是通过打补丁的方式进行修改;Deployment 能提供滚动式自定义自控制的更新;对Deployment 来讲,我们在实现更新时还可以实现控制更新节奏和更新逻辑。
比如说 Deployment 控制 5 个 pod 副本,pod 的期望值是 5个,但是升级的时候需要额外多几个 pod,那我们控制器可以控制在 5个 pod 副本之外还能再增加几个 pod 副本;比方说能多一个,但是不能少,那么升级的时候就是先增加一个,再删除一个,增加一个删除一个,始终保持pod 副本数是 5个;还有一种情况,最多允许多一个,最少允许少一个,也就是最多 6个,最少 4个,第一次加一个,删除两个,第二次加两个,删除两个,依次类推,可以自己控制更新方式,这种滚动更新需要加 readinessProbe 和 livenessProbe 探测,确保 pod 中容器里的应用都正常启动了才删除之前的 pod。
启动第一步,刚更新第一批就暂停了也可以;假如目标是 5个,允许一个也不能少,允许最多可以 10个,那一次加 5个即可;这就是我们可以自己控制节奏来控制更新的方法。
通过 Deployment 对象,你可以轻松的做到以下事情:
# 查看 Deployment 资源对象由哪几部分组成
[root@k8s-master01 ~]# kubectl explain deployment
KIND: Deployment
VERSION: apps/v1
DESCRIPTION:
Deployment enables declarative updates for Pods and ReplicaSets.
FIELDS:
apiVersion # 该资源使用的 api 版本
kind # 创建的资源是什么
metadata
参考官方文档:Deployment | Kubernetes
deployment 是一个三级结构,deployment 管理 replicaset,replicaset 管理 pod。把 myapp-blue-v1.tar.gz 和 myapp-blue-v2.tar.gz 上传到 node1 和 node2 上,手动解压:
[root@k8s-node1 ~]# ctr -n=k8s.io images import myapp-blue-v1.tar.gz
[root@k8s-node1 ~]# ctr -n=k8s.io images import myapp-blue-v1.tar.gz
[root@k8s-node2 ~]# ctr -n=k8s.io images import myapp-blue-v1.tar.gz
[root@k8s-node2 ~]# ctr -n=k8s.io images import myapp-blue-v1.tar.gz
# 用 deployment 创建一个 pod
[root@k8s-master01 ~]# vim deploy-demo.yaml
apiVersion: apps/v1 # deployment对应的api版本
kind: Deployment # 创建的资源是 deployment
metadata:
name: myapp-v1 # deployment 的名字
spec:
replicas: 2 # deployment 管理的 pod 副本数
selector: # 标签选择器
matchLabels: # matchLabels下定义的标签需要跟 template.metadata.labels 定义的标签一致
app: myapp
version: v1
template:
metadata:
labels:
app: myapp
version: v1
spec: # 定义容器的属性
containers:
- name: myapp
image: janakiramm/myapp:v1 # 容器使用的镜像
imagePullPolicy: IfNotPresent # 镜像拉取策略
ports:
- containerPort: 80 # 容器里的应用的端口
startupProbe:
periodSeconds: 5
initialDelaySeconds: 20
timeoutSeconds: 10
httpGet:
scheme: HTTP
port: 80
path: /
livenessProbe:
periodSeconds: 5
initialDelaySeconds: 20
timeoutSeconds: 10
httpGet:
scheme: HTTP
port: 80
path: /
readinessProbe:
periodSeconds: 5
initialDelaySeconds: 20
timeoutSeconds: 10
httpGet:
scheme: HTTP
port: 80
path: /
# 更新资源清单文件:
[root@k8s-master01 ~]# kubectl apply -f deploy-demo.yaml
# 在 Deployment 中 kubectl apply:表示声明式的定义,既可以创建资源,也可以动态更新资源
# 查看 deploy 状态:
[root@k8s-master01 ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
myapp-v1 2/2 2 2 101s
# 查看 rs 状态:
# 创建的控制器名字是 myapp-v1-6bd64fd79
[root@k8s-master01 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp-v1-6bd64fd79 2 2 2 84s
# 创建 deploy 的时候也会创建一个 rs(replicaset),6bd64fd79 这个随机数字是我们引用 pod 的模板 template 的名字的 hash 值。
# 请注意,ReplicaSet 的名称始终设置为 [DEPLOYMENT-NAME]-[RANDOM-STRING]。RANDOM-STRING 是随机生成的。
[root@k8s-master01 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-v1-6bd64fd79-9mbg4 1/1 Running 0 84m 10.244.169.184 k8s-node2
myapp-v1-6bd64fd79-qm469 1/1 Running 0 84m 10.244.36.106 k8s-node1
# 请求刚才创建的pod资源,访问的服务内容都是一样的
[root@k8s-master01 ~]# curl 10.244.169.184
Sample Deployment