介绍
pod是k8s的最小的管理单元,在k8s中,可以按照pod的创建方式分为两类。
- 自主式pod:由k8s直接创建的pod,这种pod删除后就没有了。也不会重建。
控制器创建的pod:k8s通过控制器创建的pod,这种pod删除后还会重建,删除控制器pod也会被删除。
什么是控制器
pod控制器是管理pod的中间层,使用pod控制器后,只需告诉控制器想要多少个什么样的po就可以了,它会创建出满足条件的pod,如果pod出现问题,它会基于指定策略出现编排pod。
在k8s中常见的pod控制器有以下几种:ReplicationController:比较原始的控制器,已被弃用,由ReplicaSet替代。
- ReplicaSet:保证副本数量一直维持在期望值,并支持pod数量的扩缩容,镜像版本升级。
- Deployement:(最常用)通过控制ReplicaSet来控制pod,支持滚动更新,回退版本。
- Horizontal Pod AutoScaler:可以根据集群负载均衡自动水平调整pod数量,实现削锋填谷。
- DaemonSet:在集群中指定node运行且仅允许一个副本,一般用于守护进程类的任务。
- Job:它创建出来的pod只要完成任务就立即退出,不需要重建或重启,用于执行一次任务。
- CronJob:它创建的Pod负责周期性任务控制,不需要持续后台运行。
-
ReplicaSet(RS)
ReplicaSet用于保证一定数量的Pod正常运行,它会持续监听这些pod的运行状态,一旦Pod发生故障,就会重启或重建,同时支持对pod数量的扩缩容和版本升降级。

ReplicaSet资源清单文件:apiVersion: apps/v1 # 版本号kind: ReplicaSet # 类型metadata: # 元数据name: # rs名称namespace: # 所属命名空间labels: #标签controller: rsspec: # 详情描述replicas: 3 # 副本数量selector: # 选择器,通过它指定该控制器管理哪些podmatchLabels: # Labels匹配规则app: nginx-podmatchExpressions: # Expressions匹配规则- {key: app, operator: In, values: [nginx-pod]}template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1ports:- containerPort: 80
在这里,需要了解的新配置是spec下面的几个选项。
replicas:指定副本数量,就是创建出来的pod个数,默认1。
- selector:选择器,这里采用的是Label Selector,用来建立与pod之间的联系。
- template:模板,就是创建pod所使用的模板。
示例脚本:
apiVersion: apps/v1kind: ReplicaSetmetadata:name: pc-replicasetnamespace: devspec:replicas: 3selector:matchLabels:app: nginx-podtemplate:metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1
# 查看当前控制器创建出来的pod# 这里发现控制器创建出来的pod的名称是在控制器名称后面拼接了-xxxxx随机码[root@k8s-master01 ~]# kubectl get pod -n devNAME READY STATUS RESTARTS AGEpc-replicaset-6vmvt 1/1 Running 0 54spc-replicaset-fmb8f 1/1 Running 0 54spc-replicaset-snrk2 1/1 Running 0 54s
扩缩容:
- 通过编辑控制器元信息实现,kubectl edit rs [rsname] -n [namespace] 改变其副本数保存即可(类似vim操作)
通过纯命令kubectl scale rs [rsname] —replicas=3 -n [namespace]
镜像升级
通过编辑控制器元信息实现,kubectl edit rs [rsname] -n [namespace] 改变其镜像地址保存即可(类似vim操作)
通过纯命令kubectl set image rs [rsname] [containername]=[image] -n [nsname]。例如:kubectl set image rs pc-replicaset nginx=nginx:1.17.1 -n dev
Deployment(deploy)
在k8s1.2版本中引入,用来管理ReplicaSet,所以在ReplicaSet的基础上增加了发布停止、继续、滚动升级、回滚。

Deployment主要功能有以下几点:支持ReplicaSet所有功能。
- 支持发布停止,继续。
- 支持滚动升级和回滚版本。
Deployment的资源清单文件:
apiVersion: apps/v1 # 版本号kind: Deployment # 类型metadata: # 元数据name: # rs名称namespace: # 所属命名空间labels: #标签controller: deployspec: # 详情描述replicas: 3 # 副本数量revisionHistoryLimit: 3 # 保留历史版本paused: false # 暂停部署,默认是falseprogressDeadlineSeconds: 600 # 部署超时时间(s),默认是600strategy: # 策略type: RollingUpdate # 滚动更新策略rollingUpdate: # 滚动更新maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数maxUnavailable: 30% # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数selector: # 选择器,通过它指定该控制器管理哪些podmatchLabels: # Labels匹配规则app: nginx-podmatchExpressions: # Expressions匹配规则- {key: app, operator: In, values: [nginx-pod]}template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1ports:- containerPort: 80
示例脚本:
apiVersion: apps/v1kind: Deploymentmetadata:name: pc-deploymentnamespace: devspec:replicas: 3selector:matchLabels:app: nginx-podtemplate:metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1
镜像更新(不推荐):
deployment支持两种更新策略,重建更新和滚动更新,通过指定strategy来实现。
strategy:指定新的Pod替换旧的Pod的策略, 支持两个属性:type:指定策略类型,支持两种策略Recreate:在创建出新的Pod之前会先杀掉所有已存在的PodRollingUpdate:滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本PodrollingUpdate:当type为RollingUpdate时生效,用于为RollingUpdate设置参数,支持两个属性:maxUnavailable:用来指定在升级过程中不可用Pod的最大数量,默认为25%。maxSurge: 用来指定在升级过程中可以超过期望的Pod的最大数量,默认为25%。
重建更新
编辑示例脚本文件,在spec节点下添加更新策略
spec:strategy: # 策略type: Recreate # 重建更新
滚动更新
编辑示例脚本文件,在spec节点下添加更新策略
spec:strategy: # 策略type: RollingUpdate # 滚动更新策略rollingUpdate:maxSurge: 25%maxUnavailable: 25%
版本回退(不推荐)
kubectl rollout:版本升级相关功能,支持下面选项。
- status 显示当前升级状态。
- history 显示升级历史记录。
- pause 暂停升级过程。
- resume 继续暂停中的升级。
- restart 重启版本升级。
- undo 回滚上一级版本(可以使用 —to-revision回滚到指定版本)
示例代码
# 查看当前升级版本的状态[root@k8s-master01 ~]# kubectl rollout status deploy pc-deployment -n devdeployment "pc-deployment" successfully rolled out# 查看升级历史记录[root@k8s-master01 ~]# kubectl rollout history deploy pc-deployment -n devdeployment.apps/pc-deploymentREVISION CHANGE-CAUSE1 kubectl create --filename=pc-deployment.yaml --record=true2 kubectl create --filename=pc-deployment.yaml --record=true3 kubectl create --filename=pc-deployment.yaml --record=true# 可以发现有三次版本记录,说明完成过两次升级# 版本回滚# 这里直接使用--to-revision=1回滚到了1版本, 如果省略这个选项,就是回退到上个版本,就是2版本[root@k8s-master01 ~]# kubectl rollout undo deployment pc-deployment --to-revision=1 -n devdeployment.apps/pc-deployment rolled back# 查看发现,通过nginx镜像版本可以发现到了第一版[root@k8s-master01 ~]# kubectl get deploy -n dev -o wideNAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGESpc-deployment 4/4 4 4 74m nginx nginx:1.17.1# 查看rs,发现第一个rs中有4个pod运行,后面两个版本的rs中pod为运行# 其实deployment之所以可是实现版本的回滚,就是通过记录下历史rs来实现的,# 一旦想回滚到哪个版本,只需要将当前版本pod数量降为0,然后将回滚版本的pod提升为目标数量就可以了[root@k8s-master01 ~]# kubectl get rs -n devNAME DESIRED CURRENT READY AGEpc-deployment-6696798b78 4 4 4 78mpc-deployment-966bf7f44 0 0 0 37mpc-deployment-c848d767 0 0 0 71m
金丝雀发布
就是升级版本同时暂停,这样就只会有一部分pod做了更新,那么就可以分流一些流量给新版本的pod,同时观察新pod的状态,如果有问题就立即回滚,没有问题在继续即可。
# 更新deployment的版本,并配置暂停deployment[root@k8s-master01 ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.4 -n dev && kubectl rollout pause deployment pc-deployment -n devdeployment.apps/pc-deployment image updateddeployment.apps/pc-deployment paused#观察更新状态[root@k8s-master01 ~]# kubectl rollout status deploy pc-deployment -n devWaiting for deployment "pc-deployment" rollout to finish: 2 out of 4 new replicas have been updated...# 监控更新的过程,可以看到已经新增了一个资源,但是并未按照预期的状态去删除一个旧的资源,就是因为使用了pause暂停命令[root@k8s-master01 ~]# kubectl get rs -n dev -o wideNAME DESIRED CURRENT READY AGE CONTAINERS IMAGESpc-deployment-5d89bdfbf9 3 3 3 19m nginx nginx:1.17.1pc-deployment-675d469f8b 0 0 0 14m nginx nginx:1.17.2pc-deployment-6c9f56fcfb 2 2 2 3m16s nginx nginx:1.17.4[root@k8s-master01 ~]# kubectl get pods -n devNAME READY STATUS RESTARTS AGEpc-deployment-5d89bdfbf9-rj8sq 1/1 Running 0 7m33spc-deployment-5d89bdfbf9-ttwgg 1/1 Running 0 7m35spc-deployment-5d89bdfbf9-v4wvc 1/1 Running 0 7m34spc-deployment-6c9f56fcfb-996rt 1/1 Running 0 3m31spc-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 3m31s# 确保更新的pod没问题了,继续更新[root@k8s-master01 ~]# kubectl rollout resume deploy pc-deployment -n devdeployment.apps/pc-deployment resumed# 查看最后的更新情况[root@k8s-master01 ~]# kubectl get rs -n dev -o wideNAME DESIRED CURRENT READY AGE CONTAINERS IMAGESpc-deployment-5d89bdfbf9 0 0 0 21m nginx nginx:1.17.1pc-deployment-675d469f8b 0 0 0 16m nginx nginx:1.17.2pc-deployment-6c9f56fcfb 4 4 4 5m11s nginx nginx:1.17.4[root@k8s-master01 ~]# kubectl get pods -n devNAME READY STATUS RESTARTS AGEpc-deployment-6c9f56fcfb-7bfwh 1/1 Running 0 37spc-deployment-6c9f56fcfb-996rt 1/1 Running 0 5m27spc-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 5m27spc-deployment-6c9f56fcfb-rf84v 1/1 Running 0 37
Horizontal Pod Autoscaler(HPA)
通过监控pod的状态而自动地、智能化的实现pod的数量调整。
HPA根据pod的利用率来对比HPA定义的指标做对比,计算出需要伸缩的具体值,最后实现pod数量的调整。
安装metrics-server
metrics-server可以用来收集资源中的资源使用情况。
# 安装git[root@k8s-master01 ~]# yum install git -y# 获取metrics-server, 注意使用的版本[root@k8s-master01 ~]# git clone -b v0.3.6 https://github.com/kubernetes-incubator/metrics-server# 修改deployment, 注意修改的是镜像和初始化参数[root@k8s-master01 ~]# cd /root/metrics-server/deploy/1.8+/[root@k8s-master01 1.8+]# vim metrics-server-deployment.yaml按图中添加下面选项hostNetwork: trueimage: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6args:- --kubelet-insecure-tls- --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP

# 安装metrics-server[root@k8s-master01 1.8+]# kubectl apply -f ./# 查看pod运行情况[root@k8s-master01 1.8+]# kubectl get pod -n kube-systemmetrics-server-6b976979db-2xwbj 1/1 Running 0 90s# 使用kubectl top node 查看资源使用情况[root@k8s-master01 1.8+]# kubectl top nodeNAME CPU(cores) CPU% MEMORY(bytes) MEMORY%k8s-master01 289m 14% 1582Mi 54%k8s-node01 81m 4% 1195Mi 40%k8s-node02 72m 3% 1211Mi 41%[root@k8s-master01 1.8+]# kubectl top pod -n kube-systemNAME CPU(cores) MEMORY(bytes)coredns-6955765f44-7ptsb 3m 9Micoredns-6955765f44-vcwr5 3m 8Mietcd-master 14m 145Mi...# 至此,metrics-server安装完成
准备deployment和service
示例脚本:
apiVersion: apps/v1kind: Deploymentmetadata:name: nginxnamespace: devspec:strategy: # 策略type: RollingUpdate # 滚动更新策略replicas: 1selector:matchLabels:app: nginx-podtemplate:metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1resources: # 资源配额limits: # 限制资源(上限)cpu: "1" # CPU限制,单位是core数requests: # 请求资源(下限)cpu: "100m" # CPU限制,单位是core数
也可以通过纯命令创建
# 创建deploymentkubectl run nginx --image=nginx:1.17.1 --requests=cpu=100m -n dev# 创建servicekubectl expose deployment nginx --type=NodePort --port=80 -n dev
部署HPA
示例脚本:
apiVersion: autoscaling/v1kind: HorizontalPodAutoscalermetadata:name: pc-hpanamespace: devspec:minReplicas: 1 #最小pod数量maxReplicas: 10 #最大pod数量targetCPUUtilizationPercentage: 3 # CPU使用率指标scaleTargetRef: # 指定要控制的nginx信息apiVersion: /v1kind: Deploymentname: nginx
创建hpa之后可以通过压测工具拉高pod的cpu使用率从而使其扩容。
DaemonSet(DS)
该类型控制器可以保证集群中的每一个节点(或指定节点)都运行一个副本,一般适用于日志收集,节点监控等场景。也就是说,如果一个pod提供的功能是节点级别的(每个节点都需要一个且只需要一个),那么这类pod就适合使用DaemonSet类型的控制器创建。
特点:
- 每当向集群中添加一个节点,会自动在该节点上创建一个副本。
- 当节点被移动,pod也会被回收。
资源清单
示例脚本apiVersion: apps/v1 # 版本号 kind: DaemonSet # 类型 metadata: # 元数据 name: # rs名称 namespace: # 所属命名空间 labels: #标签 controller: daemonset spec: # 详情描述 revisionHistoryLimit: 3 # 保留历史版本 updateStrategy: # 更新策略 type: RollingUpdate # 滚动更新策略 rollingUpdate: # 滚动更新 maxUnavailable: 1 # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数 selector: # 选择器,通过它指定该控制器管理哪些pod matchLabels: # Labels匹配规则 app: nginx-pod matchExpressions: # Expressions匹配规则 - {key: app, operator: In, values: [nginx-pod]} template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本 metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.17.1 ports: - containerPort: 80
剩下job,cronjob没意义apiVersion: apps/v1 kind: DaemonSet metadata: name: pc-daemonset namespace: dev spec: selector: matchLabels: app: nginx-pod template: metadata: labels: app: nginx-pod spec: containers: - name: nginx image: nginx:1.17.1
