一、控制器概念
Pod是应用在kubernetes集群中运行的基本单位,但是往往单个的Pod运行是没有实际意义的,一般都是多个Pod组成副本集,这样可以达到高可用的效果,副本集需要通过控制器来实现,常用的控制器有Deployment、ReplicaSet、ReplicationController、StatefulSet,通过控制器来控制副本集的Pod数,从而实现Pod在节点故障时自动迁移、Pod扩展、滚动升级等功能,下面是几个常用控制器的使用场景说明
- 无状态化的应用场景可以使用Deployment、ReplicationController、ReplicaSet
- 有状态话的应用场景,需要保存数据状态,主要是指数据库、数据库集群,使用StatefulSet
- 节点支撑守护,适用于在所有或者部分节点运行Daemon,如日志、监控
- Batch批处理任务,主要适用于非常其运行的服务,主要分为一次性或者计划周期性服务
本文主要介绍无状态控制器的使用
二、Deployment
2.1.利用Deployment创建副本
Deployment是实现无状态应用副本控制器的,它通过其后端副本控制器ReplicaSet来实现,replicas副本管理通过在ReplicaSet中添加和删除Pod,RollingUpdate通过新建ReplicaSet然后逐步移除和添加Pod从而实现滚动更新,使用Deployment的主要具体场景如下
- 滚动升级RollingUpdate,后台通过ReplicaSet实现
- 多副本replicas实现,增加副本数可以提高负载
- 应用回滚Rollout,版本更新错误可以回滚
定义一个Deployment 副本数为3,Pod以模版Template的形式封装在Deployment中
cat deployment-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata: # Deployment名称、标签等元数据信息
name: deployment-nginxd-demo
labels:
app: nginx
rc: deployment
annotations:
kubernetes.io/replicationcontroller: Deployment
kubernetes.io/description: "ReplicationController Deployment Demo"
spec:
replicas: 3 # 副本数,包含3个Pod
selector: # 标签选择器,选择管理包含指定标签的Pod
matchLabels:
app: nginx
rc: deployment
template: # Pod模板定义,不包含apiVersion、kind属性,包含metadata
metadata:
labels:
app: nginx
rc: deployment
spec:
containers:
- name: nginx-deployment
image: nginx:1.7.9
imagePullPolicy: IfNotPresent
ports: # 容器端口信息
- name: http-80-port
protocol: TCP
containerPort: 80
resources: # 资源控制
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
livenessProbe: # 存活检查
httpGet:
path: /index.html
port: 80
scheme: HTTP
initialDelaySeconds: 3
periodSeconds: 5
timeoutSeconds: 2
readinessProbe: # 就绪检查
httpGet:
path: /index.html
port: 80
scheme: HTTP
initialDelaySeconds: 3
periodSeconds: 5
timeoutSeconds: 2
生成Pod
kubectl apply -f deployment-demo.yaml --record
查看Deployment列表
kubectl get deployments
kubectl describe deployments deployment-nginxd-demo
Name: deployment-nginxd-demo
Namespace: default
CreationTimestamp: Mon, 16 Mar 2020 16:13:56 +0800
Labels: app=nginx
rc=deployment
Annotations: deployment.kubernetes.io/revision: 1
kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"kubernetes.io/change-cause":"kubectl apply --filename=deployment-d...
kubernetes.io/change-cause: kubectl apply --filename=deployment-demo.yaml --record=true
kubernetes.io/description: ReplicationController Deployment Demo
kubernetes.io/replicationcontroller: Deployment
Selector: app=nginx,rc=deployment
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge # 滚动更新策略
Pod Template:
Labels: app=nginx
rc=deployment
Containers:
nginx-deployment:
Image: nginx:1.7.9
Port: 80/TCP
Host Port: 0/TCP
Limits:
cpu: 200m
memory: 256Mi
Requests:
cpu: 100m
memory: 128Mi
Liveness: http-get http://:80/index.html delay=3s timeout=2s period=5s #success=1 #failure=3
Readiness: http-get http://:80/index.html delay=3s timeout=2s period=5s #success=1 #failure=3
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: deployment-nginxd-demo-856fdfd969 (3/3 replicas created) # # 使用ReplicaSet管理的Pod数
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 42m deployment-controller Scaled up replica set deployment-nginxd-demo-856fdfd969 to 3
查看replicaset详情
kubectl describe replicasets deployment-nginxd-demo
Name: deployment-nginxd-demo-856fdfd969
Namespace: default
Selector: app=nginx,pod-template-hash=856fdfd969,rc=deployment
Labels: app=nginx
pod-template-hash=856fdfd969
rc=deployment
Annotations: deployment.kubernetes.io/desired-replicas: 3
deployment.kubernetes.io/max-replicas: 4
deployment.kubernetes.io/revision: 1
kubernetes.io/change-cause: kubectl apply --filename=deployment-demo.yaml --record=true
kubernetes.io/description: ReplicationController Deployment Demo
kubernetes.io/replicationcontroller: Deployment
Controlled By: Deployment/deployment-nginxd-demo
Replicas: 3 current / 3 desired
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=nginx
pod-template-hash=856fdfd969
rc=deployment
Containers:
nginx-deployment:
Image: nginx:1.7.9
Port: 80/TCP
Host Port: 0/TCP
Limits:
cpu: 200m
memory: 256Mi
Requests:
cpu: 100m
memory: 128Mi
Liveness: http-get http://:80/index.html delay=3s timeout=2s period=5s #success=1 #failure=3
Readiness: http-get http://:80/index.html delay=3s timeout=2s period=5s #success=1 #failure=3
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 14m replicaset-controller Created pod: deployment-nginxd-demo-856fdfd969-6pmp8
Normal SuccessfulCreate 14m replicaset-controller Created pod: deployment-nginxd-demo-856fdfd969-hddt7
Normal SuccessfulCreate 14m replicaset-controller Created pod: deployment-nginxd-demo-856fdfd969-f8p96
从上面的输出日志可以看到创建了3个Pod
查看Pod详情
kubectl describe pods eployment-nginxd-demo-856fdfd969-6pmp8
Name: deployment-nginxd-demo-856fdfd969-6pmp8
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: node-3/172.19.159.9
Start Time: Mon, 16 Mar 2020 22:01:55 +0800
Labels: app=nginx
pod-template-hash=856fdfd969
rc=deployment
Annotations: <none>
Status: Running
IP: 10.244.2.67
Controlled By: ReplicaSet/deployment-nginxd-demo-856fdfd969 # 所属的控制器
Containers:
nginx-deployment:
Container ID: docker://1b807803bea0f3eb1621400625d5affe1ffa05e46d78dbb947b247e6c38ef522
Image: nginx:1.7.9
Image ID: docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Mon, 16 Mar 2020 22:01:57 +0800
Ready: True
Restart Count: 0
Limits:
cpu: 200m
memory: 256Mi
Requests:
cpu: 100m
memory: 128Mi
Liveness: http-get http://:80/index.html delay=3s timeout=2s period=5s #success=1 #failure=3
Readiness: http-get http://:80/index.html delay=3s timeout=2s period=5s #success=1 #failure=3
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-hg24n (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-hg24n:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-hg24n
Optional: false
QoS Class: Burstable
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 16m default-scheduler Successfully assigned default/deployment-nginxd-demo-856fdfd969-6pmp8 to node-3
Normal Pulled 16m kubelet, node-3 Container image "nginx:1.7.9" already present on machine
Normal Created 16m kubelet, node-3 Created container nginx-deployment
Normal Started 16m kubelet, node-3 Started container nginx-deployment
从上面的输出可以看到pod的详细信息
Deployment的副本控制功能是由replicaset实现,replicaset生成Deployment中定义的replicas副本的数量,即创建多个副本
2.2.Deployment扩容与缩容
Deployment控制器会自动根据当前副本数目创建所需的Pod数,这些pod会自动加入到service中实现负载均衡,相反减少副本数,这些pod会自动从service中删除
手动扩容scale
kubectl scale --replicas=4 deployment deployment-nginxd-demo
kubectl get deployments deployment-nginxd-demo可以看到副本pod数变成4了
查看replicaset的详情信息观察,增加副本的个数是通过replicaset来扩容,通过模版复制新的Pod
kubectl describe replicasets deployment-nginxd-demo-856fdfd969查看replicaset详情
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 51m replicaset-controller Created pod: deployment-nginxd-demo-856fdfd969-6pmp8
Normal SuccessfulCreate 51m replicaset-controller Created pod: deployment-nginxd-demo-856fdfd969-hddt7
Normal SuccessfulCreate 51m replicaset-controller Created pod: deployment-nginxd-demo-856fdfd969-f8p96
Normal SuccessfulCreate 5m53s replicaset-controller Created pod: deployment-nginxd-demo-856fdfd969-s8f82
可以从上面的输出看到rs创建pod
缩容
kubectl scale --replicas=2 deployment deployment-nginxd-demo
kubectl describe replicasets deployment-nginxd-demo-856fdfd969
Normal SuccessfulCreate 53m replicaset-controller Created pod: deployment-nginxd-demo-856fdfd969-6pmp8
Normal SuccessfulCreate 53m replicaset-controller Created pod: deployment-nginxd-demo-856fdfd969-hddt7
Normal SuccessfulCreate 53m replicaset-controller Created pod: deployment-nginxd-demo-856fdfd969-f8p96
Normal SuccessfulCreate 8m17s replicaset-controller Created pod: deployment-nginxd-demo-856fdfd969-s8f82
Normal SuccessfulDelete 15s replicaset-controller Deleted pod: deployment-nginxd-demo-856fdfd969-6pmp8
Normal SuccessfulDelete 15s replicaset-controller Deleted pod: deployment-nginxd-demo-856fdfd969-s8f82
从上面的输出可以看到副本数从4缩减到2
Deployment的扩容是通过ReplicaSet的模版创建Pod或删除Pod实现,scale是手动扩展实现副本的机制,kubernetes还提供了另外一种副本自动扩容机制horizontalpodautoscalers(Horizontal Pod Autoscaling),即通过定义CPU的利用率实现自动的横向扩展,由于需要依赖于监控组件
2.3.滚动更新与回滚
Deployment支持滚动更新,默认创建Deployment后会增加滚动更新的策略,通过逐步替代replicas中的pod实现更新无服务中断(需要结合service)
查看滚动更新相关策略
kubectl get deployments deployment-nginxd-demo -o yaml
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
每次更新最大的数量maxSurge是replicas总数的25%,最大不可用的数量maxUnavailable为25%
当pod.template中定义的相关属性变化,如下将镜像更新到1.9.1,通过--record会记录操作命令
升级
kubectl set image deployments deployment-nginxd-demo nginx-deployment=nginx:1.9.1 --record
等待升级结果
kubectl rollout status deployment deployment-nginxd-demo
如果升级成功最后会输出
deployment "deployment-nginxd-demo" successfully rolled out
查看滚动升级前后的版本
kubectl rollout history deployment deployment-nginxd-demo
REVISION CHANGE-CAUSE
1 kubectl apply --filename=deployment-demo.yaml --record=true
2 kubectl set image deployments deployment-nginxd-demo nginx-deployment=nginx:1.9.1 --record=true
kubectl describe deployments deployment-nginxd-demo 查看升级过程
NewReplicaSet: deployment-nginxd-demo-85ff56866c (2/2 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 35m deployment-controller Scaled up replica set deployment-nginxd-demo-856fdfd969 to 4
Normal ScalingReplicaSet 26m deployment-controller Scaled down replica set deployment-nginxd-demo-856fdfd969 to 2
Normal ScalingReplicaSet 5m49s deployment-controller Scaled up replica set deployment-nginxd-demo-85ff56866c to 1
Normal ScalingReplicaSet 5m23s deployment-controller Scaled down replica set deployment-nginxd-demo-856fdfd969 to 1
Normal ScalingReplicaSet 5m23s deployment-controller Scaled up replica set deployment-nginxd-demo-85ff56866c to 2
Normal ScalingReplicaSet 4m54s deployment-controller Scaled down replica set deployment-nginxd-demo-856fdfd969 to 0
从上面的输出可以看出在滚动更新过程中新建了一个replicaSet(deployment-nginxd-demo-85ff56866c),逐渐将旧的replicaSet(deployment-nginxd-demo-856fdfd969)中的pod替换掉,直至旧的replicaSet中的Pod数为0,可以用下面的命令查看replicaSet
kubectl get replicaSets输出replicaSet列表
NAME DESIRED CURRENT READY AGE
deployment
-nginxd-demo-856fdfd969 0 0 0 92m
deployment-nginxd-demo-85ff56866c 2 2 2 18m
NAME DESIRED CURRENT READY AGE
deployment-nginxd-demo-856fdfd969 0 0 0 92m
deployment-nginxd-demo-85ff56866c 2 2 2 18m
测试是否升级成功
kubectl get pods -o wide
curl -I podIP查看返回信息
回滚到版本1 deployment.extensions/deployment-nginxd-demo
kubectl rollout undo deployment deployment-nginxd-demo --to-revision=1
查看历史版本
kubectl rollout history deployment deployment-nginxd-demo
deployment.extensions/deployment-nginxd-demo
REVISION CHANGE-CAUSE
2 kubectl set image deployments deployment-nginxd-demo nginx-deployment=nginx:1.9.1 --record=true
3 kubectl apply --filename=deployment-demo.yaml --record=true
查看Deployment详情
kubectl describe deployments deployment-nginxd-demo
测试是否会滚成功
kubectl get pods -o wide
curl -I podip
Deployment是通过ReplicaSet实现Pod副本数的管理(扩容或减少副本数),滚动更新是通过新建RS,将Pod从旧的RS逐步更新到新的RS上;相反,回滚版本将会退到指定版本的ReplicaSet上
三、ReplicaSet
控制副本数,Deployment调用ReplicaSet实现副本的控制,ReplicaSet不具备滚动升级和回滚的功能,一般使用Deployment
下面定义一个ReplicaSet
cat replicaset-demo.yaml
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
name: replicaset-demo
labels:
controller: replicaset
annotations:
kubernetes.io/description: "kubernetes replication controller"
spec:
replicas: 3
selector:
matchLabels:
controller: replicaset
template:
metadata:
labels:
controller: replicaset
spec:
containers:
- name: nginx-replicaset-demo
image: nginx:1.7.9
imagePullPolicy: IfNotPresent
ports:
- name: http-80-port
protocol: TCP
containerPort: 80
生成RS
kubectl apply -f replicaset-demo.yaml
查看RS列表
kubectl get replicasets
扩展到4个副本
kubectl scale --replicaset=4 replicaset replicaset-demo
缩减到2个副本
kubectl scale --replicas=2 replicaset replicaset-demo
与Deployment区别的是Replicaset本身是不具备滚动升级应用版本的功能的,Deployment是更高层次的副本控制器
四、ReplicationController
该控制器是早期的副本控制器,现在已经淘汰了,简单说一下,其定义方式与Deployment、ReplicaSet类似
定义一个ReplicationController
cat rc-demo.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: rc-demo
labels:
controller: replicationcontroller
annotations:
kubernetes.io/description: "kubernetes replication controller replication"
spec:
replicas: 3
selector:
controller: replicationcontroller
template:
metadata:
labels:
controller: replicationcontroller
spec:
containers:
- name: nginx-rc-demo
image: nginx:1.7.9
imagePullPolicy: IfNotPresent
ports:
- name: http-80-port
protocol: TCP
containerPort: 80
生成replicationcontroller
kubectl apply -f rc-demo.yaml
kubectl get replicationcontrollers查看rc列表
扩容到4个副本
kubectl scale --replicas=4 replicationcontroller rc-demo
缩容到2个
kubectl scale --replicas=2 replicationcontroller rc-demo
ReplicationController与ReplicaSet一样是没有滚动更新和回滚功能的