管理无状态应用控制器,作为保护过程
- replicaSet
- Deployment
- DaemonSet
管理无状态应用控制器,任务结束后退出的过程需要
- Job
- Cronjob
管理有状态应用
- StatefulSet
replicaSet
replicaSet
加入新版本代替 ReplicationController
为用户创建指定数量的控制器pod
保证副本的数量pod
副本数量符合预期状态,自动扩容和缩容功能
由三个组件组成
- 管控的pod副本有几个
- 标签选择器
- pod资源模板
[root@master-0 ~]# kubectl explain rs KIND: ReplicaSet VERSION: apps/v1 DESCRIPTION: ReplicaSet ensures that a specified number of pod replicas are running at any given time. ... ... [root@master-0 ~]# kubectl explain rs.spec KIND: ReplicaSet VERSION: apps/v1 RESOURCE: spec <Object> DESCRIPTION: Spec defines the specification of the desired behavior of the ReplicaSet. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status ReplicaSetSpec is the specification of a ReplicaSet. FIELDS: minReadySeconds <integer> Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready) replicas <integer> #副本数量 Replicas is the number of desired replicas. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller selector <Object> -required- #标签选择器 Selector is a label query over pods that should match the replica count. Label keys and values that must match in order to be controlled by this replica set. It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors template <Object> #模板,通过检查他explian可以发现它是pod的资源清单 Template is the object that describes the pod that will be created if insufficient replicas are detected. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template [root@master-0 ~]# cat rs-demo.yaml apiVersion: apps/v1 kind: ReplicaSet metadata: # rs的配置 name: myapp namespace: default spec: # rs的配置 replicas: 2 selector: matchLabels: app: myapp release: canary template: # 这里开始往下走pod的模板设置 metadata: name: myapp-pod # 这个值不值得生效,其实是创造后的rs的名称 由随机字符数字组成 labels: app: myapp release: canary spec: containers: - name: myapp-container image: nginx ports: - name: http containerPort: 80 [root@master-0 ~]# kubectl create -f rs-demo.yaml replicaset.apps/myapp created [oot@master-0 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp 2 2 2 13m
- rs可以实现动态扩缩容,同时还可以动态更新使用
edit
命令实现,但注意的是动态升级的时候需要手动执行重建pod的命令,实现金丝雀发布或灰度发布 - 但
replicaSet
并不会被直接使用,用户直接使用的控制器是Deployment
Deployment
Deployment
工作在 replicaSet
它通过控制 replicaSet
来得益于控制 pod
并且除了 replicaSet
的功能外还支持滚动更新、回滚和声明式配置,只要资源支持动态运行时修改功能,即可通过声明式的逻辑动态修改期望状态
-
deplyment 的蓝绿发布示意图
-
通常只保留10个历史版本
-
可以控制更新逻辑,设定滚动更新过程中pod的数量可以增加或减少多少,两个条件可并存;所以可以通过控制节奏达到蓝绿、灰度和金丝雀发布
-
Deploy 层级关系:Deployment 控制 ReplicaSets,ReplicaSets 控制 pods
-
基于 ymal 文件创建 deplyment
[root@master-0 ~]# kubectl explain deploy KIND: Deployment VERSION: apps/v1 DESCRIPTION: Deployment enables declarative updates for Pods and ReplicaSets. FIELDS: apiVersion <string> APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources kind <string> Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds metadata <Object> Standard object metadata. spec <Object> Specification of the desired behavior of the Deployment. status <Object> Most recently observed status of the Deployment. [root@master-0 ~]# kubectl explain deploy.spec KIND: Deployment VERSION: apps/v1 RESOURCE: spec <Object> DESCRIPTION: Specification of the desired behavior of the Deployment. DeploymentSpec is the specification of the desired behavior of the Deployment. FIELDS: minReadySeconds <integer> Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready) paused <boolean> # 启动更新时暂停,一般默认不暂停 Indicates that the deployment is paused. progressDeadlineSeconds <integer> The maximum time in seconds for a deployment to make progress before it is considered to be failed. The deployment controller will continue to process failed deployments and a condition with a ProgressDeadlineExceeded reason will be surfaced in the deployment status. Note that progress will not be estimated during the time a deployment is paused. Defaults to 600s. replicas <integer> Number of desired pods. This is a pointer to distinguish between explicit zero and not specified. Defaults to 1. revisionHistoryLimit <integer> # 保留的历史版本,默认 10 个 The number of old ReplicaSets to retain to allow rollback. This is a pointer to distinguish between explicit zero and not specified. Defaults to 10. selector <Object> -required- Label selector for pods. Existing ReplicaSets whose pods are selected by this will be the ones affected by this deployment. It must match the pod template's labels. strategy <Object> # 更新策略 The deployment strategy to use to replace existing pods with new ones. template <Object> -required- Template describes the pods that will be created. [root@master-0 ~]# kubectl explain deploy.spec.strategy KIND: Deployment VERSION: apps/v1 RESOURCE: strategy <Object> DESCRIPTION: The deployment strategy to use to replace existing pods with new ones. DeploymentStrategy describes how to replace existing pods with new ones. FIELDS: rollingUpdate <Object> #当 type 为 RollingUpdate 时可以使用该字段定义策略,控制更新粒度 Rolling update config params. Present only if DeploymentStrategyType = RollingUpdate. type <string> # Recreate 重建式更新 删一个建一个, RollingUpdate 为滚动更新 Type of deployment. Can be "Recreate" or "RollingUpdate". Default is RollingUpdate. [root@master-0 ~]# kubectl explain deploy.spec.strategy.rollingUpdate KIND: Deployment VERSION: apps/v1 RESOURCE: rollingUpdate <Object> DESCRIPTION: Rolling update config params. Present only if DeploymentStrategyType = RollingUpdate. Spec to control the desired behavior of rolling update. FIELDS: maxSurge <string> # 更新过程当中,可以超出限制的副本数量个数,两种取值方式一个为个数一个为百分比 The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to 25%. Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when the rolling update starts, such that the total number of old and new pods do not exceed 130% of desired pods. Once old pods have been killed, new ReplicaSet can be scaled up further, ensuring that total number of pods running at any time during the update is at most 130% of desired pods. maxUnavailable <string> # 更新过程中,有几个副本数量不可用 The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to 25%. Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods immediately when the rolling update starts. Once new pods are ready, old ReplicaSet can be scaled down further, followed by scaling up the new ReplicaSet, ensuring that the total number of pods available at all times during the update is at least 70% of desired pods. [root@master-0 ~]# cat deploy-demo.yaml apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 2 selector: matchLabels: app: myapp release: canary template: metadata: labels: app: myapp release: canary spec: containers: - name: myapp image: nginx ports: - name: http containerPort: 80 [root@master-0 ~]# kubectl apply -f deploy-demo.yaml # 声明式更新或创建 deployment.apps/myapp-deploy created [root@master-0 ~]# kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE myapp-deploy 2/2 2 2 3m44s [root@master-0 ~]# kubectl get rs NAME DESIRED CURRENT READY AGE myapp-deploy-7cc8498dfc 2 2 2 4m7s # 自动创建的 rs,name 值+模板的 hash 值,这样可以追踪到具体模板 [root@master-0 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE myapp-deploy-7cc8498dfc-sttxt 1/1 Running 0 4h57m myapp-deploy-7cc8498dfc-wsfb6 1/1 Running 0 4h57m
-
apply
声明式更新展示[root@master-0 ~]# vim deploy-demo.yaml # replicas 改为 3,然后用 app 声明式更新,每次的变化会发送给 APIserver,再由 APIserver 发送到 etcd 中 apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 3 selector: matchLabels: app: myapp release: canary template: metadata: labels: app: myapp release: canary spec: containers: - name: myapp image: nginx:1.7 ports: - name: http containerPort: 80 [root@master-0 ~]# kubectl apply -f deploy-demo.yaml
-
deployment
的滚动更新展示-
确认更新策略
[root@master-0 ~]# kubectl describe deploy myapp-deploy Name: myapp-deploy Namespace: default CreationTimestamp: Mon, 27 Apr 2020 11:45:30 -0400 Labels: <none> Annotations: deployment.kubernetes.io/revision: 1 Selector: app=myapp,release=canary 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=myapp release=canary Containers: myapp: Image: nginx Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Progressing True NewReplicaSetAvailable Available True MinimumReplicasAvailable OldReplicaSets: <none> NewReplicaSet: myapp-deploy-7cc8498dfc (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 42m deployment-controller Scaled up replica set myapp-deploy-7cc8498dfc to 3 [root@master-0 ~]# kubectl get pod -l app=myapp NAME READY STATUS RESTARTS AGE myapp-deploy-7cc8498dfc-d98zq 1/1 Running 0 44m myapp-deploy-7cc8498dfc-sttxt 1/1 Running 0 5h42m myapp-deploy-7cc8498dfc-wsfb6 1/1 Running 0 5h42m
-
更改模板并
apply
更新deploy
[root@master-0 ~]# vim deploy-demo.yaml # 更换 image 版本 apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 3 selector: matchLabels: app: myapp release: canary template: metadata: labels: app: myapp release: canary spec: containers: - name: myapp image: nginx:1.7 ports: - name: http containerPort: 80 [root@master-0 ~]# kubectl apply -f deploy-demo.yaml deployment.apps/myapp-deploy configured [root@master-0 ~]# kubectl get pod -l app=myapp -w # 可以看到 pod 在滚动更新 NAME READY STATUS RESTARTS AGE myapp-deploy-7cc8498dfc-d98zq 1/1 Running 0 47m myapp-deploy-7cc8498dfc-sttxt 1/1 Running 0 5h46m myapp-deploy-7cc8498dfc-wsfb6 1/1 Running 0 5h46m myapp-deploy-6d964d9c67-dd2g6 0/1 Pending 0 0s myapp-deploy-6d964d9c67-dd2g6 0/1 Pending 0 0s myapp-deploy-6d964d9c67-dd2g6 0/1 ContainerCreating 0 0s myapp-deploy-6d964d9c67-dd2g6 1/1 Running 0 80s myapp-deploy-7cc8498dfc-d98zq 1/1 Terminating 0 49m myapp-deploy-6d964d9c67-5t94c 0/1 Pending 0 0s myapp-deploy-6d964d9c67-5t94c 0/1 Pending 0 0s myapp-deploy-6d964d9c67-5t94c 0/1 ContainerCreating 0 0s myapp-deploy-7cc8498dfc-d98zq 0/1 Terminating 0 49m myapp-deploy-7cc8498dfc-d98zq 0/1 Terminating 0 49m myapp-deploy-7cc8498dfc-d98zq 0/1 Terminating 0 49m myapp-deploy-6d964d9c67-5t94c 1/1 Running 0 108s myapp-deploy-7cc8498dfc-sttxt 1/1 Terminating 0 5h49m myapp-deploy-6d964d9c67-h7sph 0/1 Pending 0 0s myapp-deploy-6d964d9c67-h7sph 0/1 Pending 0 0s myapp-deploy-6d964d9c67-h7sph 0/1 ContainerCreating 0 0s myapp-deploy-7cc8498dfc-sttxt 0/1 Terminating 0 5h49m myapp-deploy-6d964d9c67-h7sph 1/1 Running 0 6s myapp-deploy-7cc8498dfc-wsfb6 1/1 Terminating 0 5h49m myapp-deploy-7cc8498dfc-wsfb6 0/1 Terminating 0 5h49m myapp-deploy-7cc8498dfc-wsfb6 0/1 Terminating 0 5h49m myapp-deploy-7cc8498dfc-wsfb6 0/1 Terminating 0 5h49m myapp-deploy-7cc8498dfc-sttxt 0/1 Terminating 0 5h49m myapp-deploy-7cc8498dfc-sttxt 0/1 Terminating 0 5h49m [root@master-0 ~]# kubectl get rs -o wide # 可以看到历史版本,等待回滚 NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp-deploy-6d964d9c67 3 3 3 22m myapp nginx:1.7 app=myapp,pod-template-hash=6d964d9c67,release=canary myapp-deploy-7cc8498dfc 0 0 0 6h8m myapp nginx app=myapp,pod-template-hash=7cc8498dfc,release=canary
-
Deploy 的更新回滚
[root@master-0 ~]# kubectl rollout --help Manage the rollout of a resource. Valid resource types include: * deployments * daemonsets * statefulsets Examples: # Rollback to the previous deployment kubectl rollout undo deployment/abc # Check the rollout status of a daemonset kubectl rollout status daemonset/foo Available Commands: history 显示 rollout 历史 pause 标记提供的 resource 为中止状态 restart Restart a resource resume 继续一个停止的 resource status 显示 rollout 的状态 undo 撤销上一次的 rollout Usage: kubectl rollout SUBCOMMAND [options] Use "kubectl <command> --help" for more information about a given command. Use "kubectl options" for a list of global command-line options (applies to all commands). [root@master-0 ~]# kubectl rollout history deployment myapp-deploy deployment.apps/myapp-deploy REVISION CHANGE-CAUSE 1 <none> 2 <none> [root@master-0 ~]# kubectl rollout undo deployment/myapp-deploy --to-revision=1 # 指定回滚版本并执行回滚操作
-
-
Deployment 的扩容展示
-
通过打补丁
patch
的方式扩容,并修改滚动更新的策略,该方法并不会修改本地 yaml 文件,所以仅做临时修改用[root@master-0 ~]# kubectl patch deployment myapp-deploy -p '{"spec":{"replicas":5}}' # 通过 -p 指定 json 模板,其中键必须用""标注 deployment.apps/myapp-deploy patched [root@master-0 ~]# kubectl explain deploy.spec.strategy.rollingUpdate [root@master-0 ~]# kubectl patch deployment myapp-deploy -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}' deployment.apps/myapp-deploy patched
-
通过另一种
set image
的方式更新镜像,并使用 pause 方式实现金丝雀发布[root@master-0 ~]# kubectl set image deployment myapp-deploy myapp=nginx:1.6 && kubectl rollout pause deployment myapp-deploy deployment.apps/myapp-deploy image updated deployment.apps/myapp-deploy paused [root@master-0 ~]# kubectl rollout status deployment myapp-deploy #查看当前资源 rollout 的状态 Waiting for deployment "myapp-deploy" rollout to finish: 1 out of 5 new replicas have been updated... [root@master-0 ~]# kubectl rollout resume deployment myapp-deploy deployment.apps/myapp-deploy resumed [root@master-0 ~]# kubectl get rs # 查看历史版本 NAME DESIRED CURRENT READY AGE myapp-deploy-6d964d9c67 0 0 0 107m myapp-deploy-7cc8498dfc 0 0 0 7h33m myapp-deploy-7f9b4455b4 5 5 5 6m12s
-
DaemonSet
DaemonSet
用于在每个或部分满足条件的 node
节点上运行系统级功能性 pod
副本,用于实现系统级的管理功能可以将节点上的某个目录作为存储卷关联到 pod
中
有两个组件组成
-
标签选择器
-
pod资源模板
-
制作一个收集日志的
DaemonSet
不需要指定副本数,副本数是随机群规模自动生成的[root@master-0 ~]# cat ds-demo.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: myapp-ds namespace: default spec: selector: matchLabels: app: filebeat release: stable template: metadata: labels: app: filebeat release: stable spec: containers: - name: filebeat image: ikubernetes/filebeat:5.6.5-alpine env: # 对象列表 - name: REDIS_HOST # 这个 kv 是镜像内要求定义的 value: redis.default.svc.cluster.local - name: REDIS_LOG_LEVEL value: info [root@master-0 ~]# kubectl apply -f ds-demo.yaml [root@master-0 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE myapp-deploy-7cc8498dfc-4nmhd 1/1 Running 3 25d myapp-deploy-7cc8498dfc-5lkg4 1/1 Running 3 25d myapp-deploy-7cc8498dfc-9gvlj 1/1 Running 3 25d myapp-deploy-7cc8498dfc-gfp9l 1/1 Running 3 25d myapp-deploy-7cc8498dfc-qvfp8 1/1 Running 3 25d myapp-deploy-7f9b4455b4-49ssf 0/1 ImagePullBackOff 0 25d myapp-ds-9nqcj 1/1 Running 1 14d # 自动判断生成两个节点,因为不能容忍 master 污点,所以在所有 node 节点上生成 myapp-ds-pdkts 1/1 Running 1 14d
接下来为了使
filebeat
真正可运行,我们在资源清单中增加redis
的Deployment
和svc
[root@master-0 ~]# cat ds-demo.yaml apiVersion: apps/v1 kind: Deployment # 有状态服务如果要用 Deployment 作为控制器,其副本数不能超过 1 metadata: name: redis namespace: default spec: replicas: 1 selector: matchLabels: app: redis role: logstor template: metadata: labels: app: redis role: logstor spec: containers: - name: redis image: redis:4.0-alpine ports: - name: redis containerPort: 6379 --- # 两个连接紧密的资源清单可用 --- 分割写入一个 yaml 文件中 apiVersion: apps/v1 kind: DaemonSet metadata: name: filebeat-ds namespace: default spec: selector: matchLabels: app: filebeat release: stable template: metadata: labels: app: filebeat release: stable spec: containers: - name: filebeat image: ikubernetes/filebeat:5.6.5-alpine env: - name: REDIS_HOST value: redis.default.svc.cluster.local - name: REDIS_LOG_LEVEL value: info [root@master-0 ~]# kubectl apply -f ds-demo.yaml deployment.apps/redis created daemonset.apps/filebeat-ds created [root@master-0 ~]# kubectl expose deploy redis --port=6379 # 生成暴露 6379 端口的 svc [root@master-0 ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.208.0.1 <none> 443/TCP 54d redis ClusterIP 10.214.52.224 <none> 6379/TCP 11s [root@master-0 ~]# kubectl get pod NAME READY STATUS RESTARTS AGE filebeat-ds-nz5t9 1/1 Running 0 2m33s filebeat-ds-wqt42 1/1 Running 0 2m33s redis-588694bf8c-7zb98 1/1 Running 0 2m33s [root@master-0 ~]# kubectl exec -it redis-588694bf8c-7zb98 -- /bin/sh /data # netstat -tnl Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN tcp 0 0 :::6379 :::* LISTEN /data # nslookup redis.default.svc.cluster.local # 之前定义的环境变量 Server: 10.208.0.10 Address: 10.208.0.10:53 Name: redis.default.svc.cluster.local Address: 10.214.52.224 /data # redis-cli -h redis.default.svc.cluster.local redis.default.svc.cluster.local:6379> keys * (empty list or set)
这里并没有在
redis
中看到数据,尝试在filebeat
中查看解析正确,通过kill -1 ${PID}
方式重载服务未果 -
DaemonSet
的滚动更新[root@master-0 ~]# kubectl explain ds.spec.updateStrategy FIELDS: rollingUpdate <Object> Rolling update config params. Present only if type = "RollingUpdate". type <string> Type of daemon set update. Can be "RollingUpdate" or "OnDelete". Default is RollingUpdate. [root@master-0 ~]# kubectl explain ds.spec.updateStrategy.rollingUpdate FIELDS: maxUnavailable <string> # ds 的副本数只能为 1 所以只有这一种更新方式
- 另一种更新方式
[root@master-0 ~]# kubectl set image ds filebeat-ds filebeat=ikubernetes/filebeat:5.6.6-alpine daemonset.apps/filebeat-ds image updated
- 此外,我们也可以让 ds 直接暴露在宿主机的上,即使用宿主机的
net
名称空间
[root@master-0 ~]# kubectl explain pods.spec KIND: Pod VERSION: v1 RESOURCE: spec <Object> DESCRIPTION: Specification of the desired behavior of the pod. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status PodSpec is a description of a pod. FIELDS: hostIPC <boolean> # 共享宿主机 IPC Use the host's ipc namespace. Optional: Default to false. hostNetwork <boolean> # 共享宿主机的网络名称空间 Host networking requested for this pod. Use the host's network namespace. If this option is set, the ports that will be used must be specified. Default to false. hostPID <boolean> # 共享宿主机的 PID 名称空间 Use the host's pid namespace. Optional: Default to false.
Job
Job
控制器判断pod需不需要重建的标准是,该pod内的进程是否正常结束,它用来确保任务正常完成且只能完成一次性的任务
Cronjob
Cronjob
与 job
唯一不同的地方在于它用来完成周期性任务,此外它还能处理和解决周期性任务重叠时如何解决的问题
StatefulSet
StatefulSet
每个pod独立管理,它可以将应用的恢复任务定义为脚本并将其规定成为pod资源模板,但配置方式及恢复操作依旧是难点 k8s 1.2+
版本后开始支持 TPR Third Party Resources
即第三方资源,直到 1.7 版本废除重建为 CDR Custom Defined Resources
即用户自定义资源,允许将运维的操作技能封装进去定义为一种特殊资源,还可借助 Operator
灌入运维技能,但目前 Operator
支持的有状态应用依然很少,只有etcd、普罗米修斯等区区几个
helm
k8s提供的类似yum功能,能智能创建和部署应用如redis