目录
4.4.2再用statefulset控制器类型 创建nginx pod资源,并创建无头服务资源
八:Horizontal Pod Autoscaler(HPA)
Pod是kubernetes的最小管理单元,在kubernetes中,按照pod的创建方式可以将其分为两类:
什么是Pod控制器?
Pod控制器是管理pod的中间层,使用Pod控制器之后,只需要告诉Pod控制器,想要多少个什么样的Pod就可以了,它会创建出满足条件的Pod并确保每一个Pod资源处于用户期望的目标状态。如果Pod资源在运行中出现故障,它会基于指定策略重新编排Pod。
在kubernetes中,有很多类型的pod控制器,每种都有自己的适合的场景,常见的有下面这些:
- ReplicationController:比较原始的pod控制器,已经被废弃,由ReplicaSet替代
- ReplicaSet:保证副本数量一直维持在期望值,并支持pod数量扩缩容,镜像版本升级
- Deployment:通过控制ReplicaSet来控制Pod,并支持滚动升级、回退版本
- Horizontal Pod Autoscaler:可以根据集群负载自动水平调整Pod的数量,实现削峰填谷
- DaemonSet:在集群中的指定Node上运行且仅运行一个副本,一般用于守护进程类的任务
- Job:它创建出来的pod只要完成任务就立即退出,不需要重启或重建,用于执行一次性任务
- Cronjob:它创建的Pod负责周期性任务控制,不需要持续后台运行
- StatefulSet:管理有状态应用
controllers:在集群上管理和运行容器的对象通过label-selector相关联
Pod通过控制器实现应用的运维,如伸缩,升级等
Deployment主要功能有下面几个:
特点:
- [root@master ~]# vim nginx-deployment.yaml
-
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: nginx-deployment
- labels:
- app: nginx
- spec:
- replicas: 3
- selector:
- matchLabels:
- app: nginx
- template:
- metadata:
- labels:
- app: nginx
- spec:
- containers:
- - name: nginx
- image: nginx:1.15.4
- ports:
- - containerPort: 80
- kubectl create -f nginx-deployment.yaml
- kubectl get pods,deploy,rs
查看控制器
kubectl edit deployment/nginx-deployment
查看历史版本
kubectl rollout history deployment/nginx-deployment
ReplicaSet的主要作用是保证一定数量的pod正常运行,它会持续监听这些Pod的运行状态,一旦Pod发生故障,就会重启或重建。同时它还支持对pod数量的扩缩容和镜像版本的升降级。
- apiVersion: apps/v1 # 版本号
- kind: ReplicaSet # 类型
- metadata: # 元数据
- name: # rs名称
- namespace: # 所属命名空间
- labels: #标签
- controller: rs
- spec: # 详情描述
- replicas: 3 # 副本数量
- 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
在这里面,需要新了解的配置项就是spec
下面几个选项:
replicas:指定副本数量,其实就是当前rs创建出来的pod的数量,默认为1
selector:选择器,它的作用是建立pod控制器和pod之间的关联关系,采用的Label Selector机制。在pod模板上定义label,在控制器上定义选择器,就可以表明当前控制器能管理哪些pod了
template:模板,就是当前控制器创建pod所使用的模板板,里面其实就是前一章学过的pod的定义
特点:
- 解决Pod独立生命周期,保持Pod启动顺序和唯一性
- 稳定,唯一的网络标识符,持久存储(例如: etcd 配置文件,节点地址发生变化,将无法使用)
- 有序,优雅的部署和扩展、删除和终止(例如: mysql 主从关系,先启动主,再启动从)
- 有序,滚动更新
应用场景: 数据库
无状态:
有状态:
service:一组Pod访问策略,提供cluster-IP群集之间通讯,还提供负载均衡和服务发现。
Headless service无头服务: 不需要cluster-IP,直接绑定具体的Pod的IP(当Pod的IP地址是动态变化时,所以常用于绑定DNS访问)
ps:k8s暴露服务的方式主要就3种:ingress loadbalancer(SLB/ALB k8s集群外的负载均衡器Ng、haproxy、KONG、traefil等等)service
- # vim pod.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: dns-test
- spec:
- containers:
- - name: busybox
- image: busybox:1.28.4
- args:
- - /bin/sh
- - -c
- - sleep 36000
- restartPolicy: Never
- 创建dns资源
- # kubectl create -f pod.yaml
-
- # kubectl get pods
- # vim sts.yaml
- apiVersion: v1
- kind: Service
- metadata:
- name: nginx
- labels:
- app: nginx
- spec:
- ports:
- - port: 80
- name: web
- clusterIP: None
- selector:
- app: nginx
- ---
- apiVersion: apps/v1
- kind: StatefulSet
- metadata:
- name: nginx-statefulset
- namespace: default
- spec:
- serviceName: nginx
- replicas: 3
- selector:
- matchLabels:
- app: nginx
- template:
- metadata:
- labels:
- app: nginx
- spec:
- containers:
- - name: nginx
- image: nginx:latest
- ports:
- - containerPort: 80
- # kubectl create -f sts.yaml
- 有状态化创建的pod,是自动进行打标签进行区分
- # kubectl get pods
-
- # kubectl get pods,svc
-
- 验证DNS解析
- # kubectl exec -it dns-test.sh
- 解析pod的唯一域名和自身的IP
StatefulSet与Deployment区别:
StatefulSet创建的pod是有身份的!
身份三要素:
域名 nginx-statefulset-0.nginx
主机名 nginx-statefulset-0
存储 (PVC)
特点:
在每一个Node上运行一个Pod
新加入的Node也同样会自动运行一个Pod
应用场景:Agent、监控
DaemonSet | Kubernetes
官方案例(监控)
用DaemonSet 控制器类型创建nginx pod资源,没有指定副本replicats,它会根据node节点的个数创建,如果再新加一个node节点,也会给新node节点创建pod
- # vim ds.yaml
- apiVersion: apps/v1
- kind: DaemonSet
- metadata:
- name: nginx-deployment
- labels:
- app: nginx
- spec:
- selector:
- matchLabels:
- app: nginx
- template:
- metadata:
- labels:
- app: nginx
- spec:
- containers:
- - name: nginx
- image: nginx:1.15.4
- ports:
- - containerPort: 80
- # kubectl apply -f ds.yaml
-
- DaemonSet会在每个node节点都创建一个Pod
- # kubectl get pods
-
- # kubectl get pods -o wide
- 如果再新加一个node节点,也会给新node节点创建pod
Job分为普通任务(Job)和定时任务(CronJob)
一次性执行
应用场景:离线数据处理,视频解码等业务
官方案例:应用大数据场景
示例:
用job控制器类型创建资源,执行算圆周率的命令,保持后2000位,创建过程等同于在计算
,重试次数默认是6次,修改为4次,当遇到异常时Never状态会重启,所以要设定次数。
- # vim job.yaml
- apiVersion: batch/v1
- kind: Job
- metadata:
- name: pi
- spec:
- template:
- spec:
- containers:
- - name: pi
- image: perl:5.34.0
- command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
- restartPolicy: Never
- backoffLimit: 4
- 在node节点提前下载perl镜像,因为镜像比较大所以提前下载好
- node1 node2节点:
- # docker pull perl
-
- 创建过程等同于在计算
- # kubectl apply -f job.yaml
- job.batch/pi created
-
- 查看状态
- # kubectl get pods
- # kubectl describe pod pi-tkdlc
-
- 查看日志,看计算结果,结果输出到控制台
- # kubectl logs pi-tkdlc
- 3.141592653589793.............................................共2000位
查看日志,看计算结果,结果输出到控制台
周期性任务,像Linux的Crontab一样。
周期性任务
应用场景:通知,备份
Running Automated Tasks with a CronJob | Kubernetes
示例:
每隔一分钟输出一条信息,打印hello
- # vim cronjob.yaml
- apiVersion: batch/v1beta1
- kind: CronJob
- metadata:
- name: hello
- spec:
- schedule: "*/1 * * * *"
- jobTemplate:
- spec:
- template:
- spec:
- containers:
- - name: hello
- image: busybox
- args:
- - /bin/sh
- - -c
- - date; echo Hello from the Kubernetes cluster
- restartPolicy: OnFailure
-
- busybox 是linux内核镜像
- # kubectl create -f cronjob.yaml
- # kubectl get cronjob
- NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
- hello */1 * * * * False 0
25s - # kubectl get pods
- 查看日志,内容输出到控制台
- # kubectl logs hello-1659577380-lfblb
- Mon Feb 17 05:29:09 UTC 2020
- Hello from the Kubernetes cluster
-
- 等待一分钟后又会再执行一次
- # kubectl get pods
- # kubectl logs hello-1659577380-lfblb
-
- 最后删除资源,不然第二天服务器宕机
- # kubectl delete -f cronjob.yaml
Kubernetes期望可以实现通过监测Pod的使用情况,实现pod数量的自动调整,于是就产生了Horizontal Pod Autoscaler(HPA)这种控制器。
HPA可以获取每个Pod利用率,然后和HPA中定义的指标进行对比,同时计算出需要伸缩的具体值,最后实现Pod的数量的调整。其实HPA与之前的Deployment一样,也属于一种Kubernetes资源对象,它通过追踪分析RC控制的所有目标Pod的负载变化情况,来确定是否需要针对性地调整目标Pod的副本数,这是HPA的实现原理。
接下来,来做一个实验
- # 安装git
- [root@master ~]# yum install git -y
- # 获取metrics-server, 注意使用的版本
- [root@master~]# git clone -b v0.3.6 https://github.com/kubernetes-incubator/metrics-server
- # 修改deployment, 注意修改的是镜像和初始化参数
- [root@master~]# cd /root/metrics-server/deploy/1.8+/
- [root@master 1.8+]# vim metrics-server-deployment.yaml
- 按图中添加下面选项
- hostNetwork: true
- image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6
- args:
- - --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-system
- metrics-server-6b976979db-2xwbj 1/1 Running 0 90s
-
- # 使用kubectl top node 查看资源使用情况
- [root@k8s-master01 1.8+]# kubectl top node
- NAME 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-system
- NAME CPU(cores) MEMORY(bytes)
- coredns-6955765f44-7ptsb 3m 9Mi
- coredns-6955765f44-vcwr5 3m 8Mi
- etcd-master 14m 145Mi
- ...
- # 至此,metrics-server安装完成
创建pc-hpa-pod.yaml文件:
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: nginx
- namespace: dev
- spec:
- strategy: # 策略
- type: RollingUpdate # 滚动更新策略
- replicas: 1
- selector:
- matchLabels:
- app: nginx-pod
- template:
- metadata:
- labels:
- app: nginx-pod
- spec:
- containers:
- - name: nginx
- image: nginx:1.17.1
- resources: # 资源配额
- limits: # 限制资源(上限)
- cpu: "1" # CPU限制,单位是core数
- requests: # 请求资源(下限)
- cpu: "100m" # CPU限制,单位是core数
- # 创建service
- [root@k8s-master01 1.8+]# kubectl create -f pc-hpa-pod.yaml
- # 查看
- [root@k8s-master01 1.8+]# kubectl get deployment,pod,svc -n dev
- NAME READY UP-TO-DATE AVAILABLE AGE
- deployment.apps/nginx 1/1 1 1 47s
-
- NAME READY STATUS RESTARTS AGE
- pod/nginx-7df9756ccc-bh8dr 1/1 Running 0 47s
-
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- service/nginx NodePort 10.101.18.29 <none> 80:31830/TCP 35s
- apiVersion: autoscaling/v1
- kind: HorizontalPodAutoscaler
- metadata:
- name: pc-hpa
- namespace: dev
- spec:
- minReplicas: 1 #最小pod数量
- maxReplicas: 10 #最大pod数量
- targetCPUUtilizationPercentage: 3 # CPU使用率指标
- scaleTargetRef: # 指定要控制的nginx信息
- apiVersion: apps/v1
- kind: Deployment
- name: nginx
- # 创建hpa
- [root@k8s-master01 1.8+]# kubectl create -f pc-hpa.yaml
- horizontalpodautoscaler.autoscaling/pc-hpa created
-
- # 查看hpa
- [root@k8s-master01 1.8+]# kubectl get hpa -n dev
- NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
- pc-hpa Deployment/nginx 0%/3% 1 10 1 62s
使用压测工具对service地址192.168.223.30:31830
进行压测,然后通过控制台查看hpa和pod的变化
hpa变化
- [root@k8s-master01 ~]# kubectl get hpa -n dev -w
- NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
- pc-hpa Deployment/nginx 0%/3% 1 10 1 4m11s
- pc-hpa Deployment/nginx 0%/3% 1 10 1 5m19s
- pc-hpa Deployment/nginx 22%/3% 1 10 1 6m50s
- pc-hpa Deployment/nginx 22%/3% 1 10 4 7m5s
- pc-hpa Deployment/nginx 22%/3% 1 10 8 7m21s
- pc-hpa Deployment/nginx 6%/3% 1 10 8 7m51s
- pc-hpa Deployment/nginx 0%/3% 1 10 8 9m6s
- pc-hpa Deployment/nginx 0%/3% 1 10 8 13m
- pc-hpa Deployment/nginx 0%/3% 1 10 1 14m
deployment变化
- [root@k8s-master01 ~]# kubectl get deployment -n dev -w
- NAME READY UP-TO-DATE AVAILABLE AGE
- nginx 1/1 1 1 11m
- nginx 1/4 1 1 13m
- nginx 1/4 1 1 13m
- nginx 1/4 1 1 13m
- nginx 1/4 4 1 13m
- nginx 1/8 4 1 14m
- nginx 1/8 4 1 14m
- nginx 1/8 4 1 14m
- nginx 1/8 8 1 14m
- nginx 2/8 8 2 14m
- nginx 3/8 8 3 14m
- nginx 4/8 8 4 14m
- nginx 5/8 8 5 14m
- nginx 6/8 8 6 14m
- nginx 7/8 8 7 14m
- nginx 8/8 8 8 15m
- nginx 8/1 8 8 20m
- nginx 8/1 8 8 20m
- nginx 1/1 1 1 20m
pod变化
- [root@k8s-master01 ~]# kubectl get pods -n dev -w
- NAME READY STATUS RESTARTS AGE
- nginx-7df9756ccc-bh8dr 1/1 Running 0 11m
- nginx-7df9756ccc-cpgrv 0/1 Pending 0 0s
- nginx-7df9756ccc-8zhwk 0/1 Pending 0 0s
- nginx-7df9756ccc-rr9bn 0/1 Pending 0 0s
- nginx-7df9756ccc-cpgrv 0/1 ContainerCreating 0 0s
- nginx-7df9756ccc-8zhwk 0/1 ContainerCreating 0 0s
- nginx-7df9756ccc-rr9bn 0/1 ContainerCreating 0 0s
- nginx-7df9756ccc-m9gsj 0/1 Pending 0 0s
- nginx-7df9756ccc-g56qb 0/1 Pending 0 0s
- nginx-7df9756ccc-sl9c6 0/1 Pending 0 0s
- nginx-7df9756ccc-fgst7 0/1 Pending 0 0s
- nginx-7df9756ccc-g56qb 0/1 ContainerCreating 0 0s
- nginx-7df9756ccc-m9gsj 0/1 ContainerCreating 0 0s
- nginx-7df9756ccc-sl9c6 0/1 ContainerCreating 0 0s
- nginx-7df9756ccc-fgst7 0/1 ContainerCreating 0 0s
- nginx-7df9756ccc-8zhwk 1/1 Running 0 19s
- nginx-7df9756ccc-rr9bn 1/1 Running 0 30s
- nginx-7df9756ccc-m9gsj 1/1 Running 0 21s
- nginx-7df9756ccc-cpgrv 1/1 Running 0 47s
- nginx-7df9756ccc-sl9c6 1/1 Running 0 33s
- nginx-7df9756ccc-g56qb 1/1 Running 0 48s
- nginx-7df9756ccc-fgst7 1/1 Running 0 66s
- nginx-7df9756ccc-fgst7 1/1 Terminating 0 6m50s
- nginx-7df9756ccc-8zhwk 1/1 Terminating 0 7m5s
- nginx-7df9756ccc-cpgrv 1/1 Terminating 0 7m5s
- nginx-7df9756ccc-g56qb 1/1 Terminating 0 6m50s
- nginx-7df9756ccc-rr9bn 1/1 Terminating 0 7m5s
- nginx-7df9756ccc-m9gsj 1/1 Terminating 0 6m50s
- nginx-7df9756ccc-sl9c6 1/1 Terminating 0 6m50s