控制器是 k8s内置的管理工具。可以帮助用户实现 Pod的自动部署、自维护、扩容、滚动更新等功能的自动化程序。
为什么要使用控制器?
最常用的无状态服务控制器,由 Deploymen、ReplicaSet、Pod 组成、支持集群扩容缩容滚动、更新、自动维护 Pod 可用性及·副本量等功能
ReplicaSet 和 Pod 由 Deployment 自动管理,用户无需干预
- # 清理 Pod ,使用控制器创建
- [root@master ~]# kubectl delete pod --all
- # 资源对象模板
- [root@master ~]# kubectl create deployment myweb --image=myos:httpd --dry-run=client -o yaml
- [root@master ~]# vim mydeploy.yaml
- ---
- kind: Deployment # 资源对象类型
- apiVersion: apps/v1 # 版本
- metadata: # 元数据
- name: myweb # 名称
- spec: # 详细定义
- replicas: 2 # 副本数量
- selector: # 定义标签选择器
- matchLabels: # 支持 matchExpressions 表达式语法
- app: httpd # 通过标签来确定那个 Pod 由它来管理
- template: # 定义用来创建 Pod 的模板,以下为 Pod 定义
- metadata: # Pod元数据
- labels: # 名称由控制器生成
- app: httpd # 这里只能定义标签
- spec: # Pod的详细定义
- restartPolicy: Always # 重启策略
- containers: # 容器定义
- - name: apache # 容器名称
- image: myos:httpd # 创建容器使用的镜像
- imagePullPolicy: Always # 镜像下载策略
-
- # 创建 Deployment
- [root@master ~]# kubectl apply -f mydeploy.yaml
- deployment.apps/myweb created
- [root@master ~]# kubectl get deployments
- NAME READY UP-TO-DATE AVAILABLE AGE
- myweb 2/2 2 2 68s
- [root@master ~]# kubectl get replicasets
- NAME DESIRED CURRENT READY AGE
- myweb-64b544dcbc 2 2 2 73s
- [root@master ~]# kubectl get pods
- NAME READY STATUS RESTARTS AGE
- myweb-64b544dcbc-5mhqn 1/1 Running 0 76s
- myweb-64b544dcbc-nt6tz 1/1 Running 0 76s
如何访问 Deployment 资源?
Deployment 管理多个 Pod,可以使用服务对其资源进行访问
- # 创建服务访问集群
- [root@master ~]# vim websvc.yaml
- ---
- kind: Service
- apiVersion: v1
- metadata:
- name: websvc
- spec:
- type: ClusterIP
- clusterIP: 10.245.1.80
- selector:
- app: httpd
- ports:
- - protocol: TCP
- port: 80
- targetPort: 80
-
- [root@master ~]# kubectl apply -f websvc.yaml
- service/websvc created
- [root@master ~]# curl -m 3 http://10.245.1.80
- Welcome to The Apache.
- # 自维护自治理
- [root@master ~]# kubectl get pods
- NAME READY STATUS RESTARTS AGE
- myweb-64b544dcbc-5mhqn 1/1 Running 0 4m16s
- myweb-64b544dcbc-nt6tz 1/1 Running 0 4m16s
-
- # Pod 被删除后,Deploy 会自动创建新的 Pod 来维护集群的完整性
- [root@master ~]# kubectl delete pod myweb-64b544dcbc-5mhqn
- pod "myweb-64b544dcbc-5mhqn" deleted
- [root@master ~]# kubectl get pods
- NAME READY STATUS RESTARTS AGE
- myweb-64b544dcbc-g8l9p 1/1 Running 0 3s
- myweb-64b544dcbc-nt6tz 1/1 Running 0 4m25s
- # 设置 1 Pod 集群
- [root@master ~]# kubectl scale deployment myweb --replicas=1
- deployment.apps/myweb scaled
- [root@master ~]# kubectl get pods
- NAME READY STATUS RESTARTS AGE
- myweb-64b544dcbc-nt6tz 1/1 Running 0 5m46s
- # 设置 3 Pod 集群
- [root@master ~]# kubectl scale deployment myweb --replicas=3
- deployment.apps/myweb scaled
- [root@master ~]# kubectl get pods
- NAME READY STATUS RESTARTS AGE
- myweb-64b544dcbc-5sf5z 1/1 Running 0 3s
- myweb-64b544dcbc-6r6dw 1/1 Running 0 3s
- myweb-64b544dcbc-nt6tz 1/1 Running 0 5m56s
- # 查看历史版本
- [root@master ~]# kubectl rollout history deployment myweb
- deployment.apps/myweb
- REVISION CHANGE-CAUSE
- 1
-
- # 添加注释信息
- [root@master ~]# kubectl annotate deployments myweb kubernetes.io/change-cause="httpd.v1"
- deployment.apps/myweb annotated
- [root@master ~]# kubectl rollout history deployment myweb
- deployment.apps/myweb
- REVISION CHANGE-CAUSE
- 1 httpd.v1
- # 修改镜像,滚动更新集群
- [root@master ~]# kubectl set image deployment myweb apache=myos:nginx
- deployment.apps/myweb image updated
- # 给新版本添加注释信息
- [root@master ~]# kubectl annotate deployments myweb kubernetes.io/change-cause="nginx.v1"
- deployment.apps/myweb annotated
- # 查看历史版本信息
- [root@master ~]# kubectl rollout history deployment myweb
- deployment.apps/myweb
- REVISION CHANGE-CAUSE
- 1 httpd.v1
- 2 nginx.v1
-
- # 访问验证服务
- [root@master ~]# curl -m 3 http://10.245.1.80
- Nginx is running !
- # 历史版本与回滚
- [root@master ~]# kubectl rollout undo deployment myweb --to-revision 1
- deployment.apps/myweb rolled back
- [root@master ~]# curl -m 3 http://10.245.1.80
- Welcome to The Apache.
-
- [root@master ~]# kubectl rollout history deployment myweb
- deployment.apps/myweb
- REVISION CHANGE-CAUSE
- 2 nginx.v1
- 3 httpd.v1
-
- # 删除控制器方法1
- [root@master ~]# kubectl delete deployments myweb
- deployment.apps "myweb" deleted
- # 删除控制器方法2
- [root@master ~]# kubectl delete -f mydeploy.yaml
- deployment.apps "myweb" deleted
- [root@master ~]# cp -a mydeploy.yaml myds.yaml
- [root@master ~]# vim myds.yaml
- ---
- kind: DaemonSet # 资源对象类型
- apiVersion: apps/v1
- metadata:
- name: myds # 控制器名称
- spec:
- # replicas: 2 # 删除副本参数
- selector:
- matchLabels:
- app: httpd
- template:
- metadata:
- labels:
- app: httpd
- spec:
- restartPolicy: Always
- containers:
- - name: apache
- image: myos:httpd
- imagePullPolicy: Always
-
- # 创建 DaemonSet 资源对象,与 node 绑定,每节点都创建容器
- [root@master ~]# kubectl apply -f myds.yaml
- daemonset.apps/myds created
- [root@master ~]# kubectl get pods -o wide
- NAME READY STATUS RESTARTS AGE IP NODE
- myds-msrcx 1/1 Running 0 31s 10.244.1.11 node-0001
- myds-lwq8l 1/1 Running 0 31s 10.244.2.17 node-0002
- myds-4wt72 1/1 Running 0 31s 10.244.3.14 node-0003
- myds-6k82t 1/1 Running 0 31s 10.244.4.15 node-0004
- myds-9c6wc 1/1 Running 0 31s 10.244.5.19 node-0005
- # 设置污点,重建 daemonset
- [root@master ~]# kubectl taint node node-0001 k=v:NoSchedule
- node/node-0001 tainted
- [root@master ~]# kubectl delete -f myds.yaml
- daemonset.apps "myds" deleted
- [root@master ~]# kubectl apply -f myds.yaml
- daemonset.apps/myds created
- # 有污点不会部署,特殊需求可以设置容忍策略
- [root@master ~]# kubectl get pods
- NAME READY STATUS RESTARTS AGE
- myds-pkdn9 1/1 Running 0 2s
- myds-pkp6b 1/1 Running 0 2s
- myds-j84cw 1/1 Running 0 2s
- myds-5c69p 1/1 Running 0 2s
- # 删除污点后会立即部署
- [root@master ~]# kubectl taint node node-0001 k=v:NoSchedule-
- node/node-0001 untainted
- [root@master ~]# kubectl get pods
- NAME READY STATUS RESTARTS AGE
- myds-2c86p 1/1 Running 0 1s
- myds-pkdn9 1/1 Running 0 9s
- myds-pkp6b 1/1 Running 0 9s
- myds-j84cw 1/1 Running 0 9s
- myds-5c69p 1/1 Running 0 9s
-
- # 删除控制器
- [root@master ~]# kubectl delete -f myds.yaml
- daemonset.apps "myds" deleted
Job 是一个单任务控制器,负责执行一次任务,保证任务在一个或多个Pod上执行成功
CronJob 像是Job的升级版,他是基于时间管理的 Job 控制器
- # 资源对象模板
- [root@master ~]# kubectl create job myjob --image=myos:8.5 --dry-run=client -o yaml -- sleep 3
- [root@master ~]# vim myjob.yaml
- ---
- kind: Job
- apiVersion: batch/v1
- metadata:
- name: myjob # 资源对象名称
- spec: # job 的详细定义
- template: # 以下定义 Pod 模板
- spec: # pod的详细定义
- restartPolicy: OnFailure # 只支持[OnFailure,Never]
- containers: # 容器定义
- - name: myjob # 容器名称
- image: myos:8.5 # 创建容器使用的镜像
- command: ["/bin/bash"] # 自定义任务,可以使用脚本
- args:
- - -c
- - |
- sleep 3
- exit $((RANDOM%2))
-
- # restartPolicy 会判断 exit 状态码
- # 状态码为 0 表示正常,其他都表示失败
-
- [root@master ~]# kubectl apply -f myjob.yaml
- job.batch/myjob created
-
- # 失败了会重启
- [root@master ~]# kubectl get pods -l job-name=myjob -w
- NAME READY STATUS RESTARTS AGE
- myjob--1-lrtbk 1/1 Running 0 2s
- myjob--1-lrtbk 0/1 Error 0 4s
- myjob--1-lrtbk 1/1 Running 1 (1s ago) 5s
- myjob--1-lrtbk 0/1 Completed 1 9s
-
- [root@master ~]# kubectl get jobs.batch
- NAME COMPLETIONS DURATION AGE
- myjob 1/1 8s 12s
-
- # 删除Job控制器
- [root@master ~]# kubectl delete -f myjob.yaml
- job.batch "myjob" deleted
资源对象案例
- # 资源对象模板
- [root@master ~]# kubectl create cronjob mycj --image=myos:8.5 --schedule='* * * * *' --dry-run=client -o yaml -- sleep 3
- [root@master ~]# vim mycj.yaml
- ---
- kind: CronJob
- apiVersion: batch/v1
- metadata:
- name: mycj # 资源名称
- spec: # cronjob 的详细定义
- schedule: "* * * * 1-5" # 时间周期:[分、时、日、月、周]
- jobTemplate: # 以下定义 Job 模板
- spec: # Job的详细定义
- template: # 创建pod的模板
- spec: # Pod的详细定义
- restartPolicy: OnFailure# 只支持[OnFailure,Never]
- containers: # 容器定义
- - name: myjob # 容器名称
- image: myos:8.5 # 创建容器使用的镜像
- command: ["/bin/bash"]# 自定义任务
- args:
- - -c
- - |
- sleep 3 # 脚本
- exit $((RANDOM%2)) # 退出状态码,失败后会重新运行
-
- [root@master ~]# kubectl apply -f mycj.yaml
- cronjob.batch/mycj created
-
- # cronjob 会按照时间周期运行
- [root@master ~]# kubectl get cronjobs
- NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
- mycj */1 * * * 1-5 False 0 <none> 4s
-
- # 按照时间周期,每分钟触发一个任务
- [root@master ~]# kubectl get jobs -w
- NAME READY STATUS RESTARTS AGE
- mycj-27808172--1-w6sbx 0/1 Pending 0 0s
- mycj-27808172--1-w6sbx 0/1 ContainerCreating 0 0s
- mycj-27808172--1-w6sbx 1/1 Running 0 1s
- mycj-27808172--1-w6sbx 0/1 Completed 1 4s
-
- # 保留三次结果,多余的会被删除
- [root@master ~]# kubectl get jobs
- NAME COMPLETIONS DURATION AGE
- mycj-27605367 1/1 31s 3m30s
- mycj-27605368 1/1 31s 2m30s
- mycj-27605369 1/1 31s 90s
- mycj-27605370 0/1 30s 30s
- [root@master ~]# kubectl get jobs
- NAME COMPLETIONS DURATION AGE
- mycj-27605368 1/1 31s 2m33s
- mycj-27605369 1/1 31s 93s
- mycj-27605370 1/1 31s 33s
-
- # 删除CJ控制器
- [root@master ~]# kubectl delete -f mycj.yaml
- cronjob.batch "mycj" deleted
StatefulSet旨在与有状态的应用及分布式系统一起使用,涉及了 Headless 服务、存储卷、DNS 等相关知识点,是一个宽泛而复杂的话题
在配置 StatefulSets 的时候首先要定义一个 Headless 的服务。
在创建 Pod的时候会自动把
- # 配置 headless 服务
- [root@master ~]# cp websvc.yaml mysvc2.yaml
- [root@master ~]# vim mysvc2.yaml
- ---
- kind: Service
- apiVersion: v1
- metadata:
- name: mysvc2 # 服务名称
- spec:
- type: ClusterIP
- clusterIP: None # 设置 IP 为 None
- selector:
- app: httpd
- ports:
- - protocol: TCP
- port: 80
- targetPort: 80
-
- [root@master ~]# kubectl apply -f mysvc2.yaml
- service/mysvc2 created
- [root@master ~]# kubectl get service mysvc2
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- mysvc2 ClusterIP None <none> 80/TCP 61s
- [root@master ~]# cp -a mydeploy.yaml mysts.yaml
- [root@master ~]# vim mysts.yaml
- ---
- kind: StatefulSet # 资源对象类型
- apiVersion: apps/v1
- metadata:
- name: mysts # 控制器名称
- spec:
- serviceName: mysvc2 # 新增 headless 服务名称
- replicas: 2
- selector:
- matchLabels:
- app: httpd
- template:
- metadata:
- labels:
- app: httpd
- spec:
- restartPolicy: Always
- containers:
- - name: apache
- image: myos:httpd
- imagePullPolicy: Always
-
- [root@master ~]# kubectl apply -f mysts.yaml
- statefulset.apps/mysts created
-
- [root@master ~]# kubectl get pods
- NAME READY STATUS RESTARTS AGE
- mysts-0 1/1 Running 0 2s
- mysts-1 1/1 Running 0 1s
-
- # Pod 名称自动注册 DNS 服务
- [root@master ~]# host mysts-0.mysvc2.default.svc.cluster.local 10.245.0.10
- Using domain server:
- Name: 10.245.0.10
- Address: 10.245.0.10#53
- Aliases:
-
- mysts-0.mysvc2.default.svc.cluster.local has address 10.244.1.81
-
- [root@master ~]# host mysvc2.default.svc.cluster.local 10.245.0.10
- Using domain server:
- Name: 10.245.0.10
- Address: 10.245.0.10#53
- Aliases:
-
- mysvc2.default.svc.cluster.local has address 10.244.2.83
- mysvc2.default.svc.cluster.local has address 10.244.1.81
-
- # 删除sts控制器
- [root@master ~]# kubectl delete -f mysts.yaml -f mysvc2.yaml
- statefulset.apps "mysts" deleted
- service "mysvc2" deleted
HorizontalPodAutoscaling 简称 HPA,可以在 Kubernetes集群中基于CPU利用率或其他应程序提供的度量指标实现水平自动伸缩的功能,自动缩放POD的数量
控制器会周期性的获取平均利用率
与目标值相比较后来调整副本数量
- # 为 Deploy 模板添加资源配额
- [root@master ~]# vim mydeploy.yaml
- ---
- kind: Deployment
- apiVersion: apps/v1
- metadata:
- name: myweb
- spec:
- replicas: 1 # 修改副本数量
- selector:
- matchLabels:
- app: httpd
- template:
- metadata:
- labels:
- app: httpd
- spec:
- restartPolicy: Always
- containers:
- - name: apache
- image: myos:httpd
- imagePullPolicy: Always
- resources: # 为该资源设置配额
- requests: # HPA 控制器会根据配额使用情况伸缩集群
- cpu: 200m # CPU 配额
-
- [root@master ~]# vim websvc.yaml
- ---
- kind: Service
- apiVersion: v1
- metadata:
- name: websvc
- spec:
- type: ClusterIP
- clusterIP: 10.245.1.80
- selector:
- app: httpd
- ports:
- - protocol: TCP
- port: 80
- targetPort: 80
-
- [root@master ~]# kubectl apply -f mydeploy.yaml -f websvc.yaml
- deployment.apps/myweb created
- service/websvc created
-
- # 验证服务
- [root@master ~]# kubectl top pods
- NAME CPU(cores) MEMORY(bytes)
- myweb-c8c66f894-2cfjv 1m 17Mi
- [root@master ~]# curl -s http://10.245.1.80
- Welcome to The Apache.
- [root@master ~]# vim myhpa.yaml
- ---
- kind: HorizontalPodAutoscaler # 资源对象类型
- apiVersion: autoscaling/v1 # 版本
- metadata: # 元数据
- name: myweb # 资源对象名称
- spec: # 详细定义
- minReplicas: 1 # 最少保留的副本数量
- maxReplicas: 5 # 最大创建的副本数量
- targetCPUUtilizationPercentage: 50 # 警戒值,以百分比计算
- scaleTargetRef: # 监控的资源对象
- kind: Deployment # 资源对象类型
- apiVersion: apps/v1 # 版本
- name: myweb # 资源对象名称
-
-
- # 创建弹性集群
- [root@master ~]# kubectl apply -f myhpa.yaml
- horizontalpodautoscaler.autoscaling/myweb created
-
- # 刚刚创建 unknown 是正常现象,最多等待 60s 就可以正常获取数据
- [root@master ~]# kubectl get horizontalpodautoscalers.autoscaling
- NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
- myweb Deployment/myweb <unknown>/50% 1 5 0 4s
-
- # 最多等待 60s 即可正常获取资源状态
- [root@master ~]# kubectl get horizontalpodautoscalers.autoscaling
- NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
- myweb Deployment/myweb 0%/50% 1 5 1 71s
持续访问 Web服务,增加CPU负载,在超过警戒值之后,会触发扩容操作,等待几秒之后发现副本数量增加了。
停止访问,让CPU空闲,为了防止集群性能抖动,副本不会立即释放,必须300秒内的平均负载小于警戒值,才开始释放副本,当副本达到最小值时候停止释放
测试时可以通过访问php 脚本增加CPU的负载
- # 终端 1 访问提高负载
- [root@master ~]# while sleep 1;do
- curl -s "http://10.245.1.80/info.php?id=100000" -o /dev/null
- done
- # 终端 2 监控 HPA 变化
- [root@master ~]# kubectl get hpa -w
- NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
- myweb Deployment/myweb 0%/50% 1 3 1 8m21s
- myweb Deployment/myweb 49%/50% 1 3 1 9m
- myweb Deployment/myweb 56%/50% 1 3 1 9m15s
- myweb Deployment/myweb 56%/50% 1 3 2 9m30s
- myweb Deployment/myweb 37%/50% 1 3 2 9m45s
- myweb Deployment/myweb 32%/50% 1 3 2 10m
- myweb Deployment/myweb 41%/50% 1 3 2 11m
- myweb Deployment/myweb 48%/50% 1 3 2 11m
- myweb Deployment/myweb 51%/50% 1 3 2 11m
- myweb Deployment/myweb 59%/50% 1 3 2 11m
- myweb Deployment/myweb 58%/50% 1 3 3 12m
- myweb Deployment/myweb 42%/50% 1 3 3 12m
- myweb Deployment/myweb 34%/50% 1 3 3 12m
-
- # 如果 300s 内平均负载小于标准值,就会自动缩减集群规模
- [root@master ~]# kubectl get hpa -w
- NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
- myweb Deployment/myweb 38%/50% 1 3 3 19m
- myweb Deployment/myweb 21%/50% 1 3 3 20m
- myweb Deployment/myweb 17%/50% 1 3 3 21m
- myweb Deployment/myweb 7%/50% 1 3 3 22m
- myweb Deployment/myweb 0%/50% 1 3 3 23m
- myweb Deployment/myweb 0%/50% 1 3 2 25m
- myweb Deployment/myweb 0%/50% 1 3 1 28m