pod
pod生命周期
pod的状态
1.挂起pending:API server创建了pod资源对象已存入etcd中,但它尚未被调度完成,或者仍处于从仓库下载镜像的过程中
2.运行中running:pod已经被调度到某节点,并且所有容器都已经被kubelet创建完成
3.成功complet:pod中所有容器都已经成功终止并且不会重启
4.失败failed:pod中所有的容器都已经终止了,并且至少有一个容器是因为失败终止的,即容器以非0状态退出或者被系统禁止
5.未知unknown:APIserver无法正常获取到pod对象的状态信息,通常是由于无法与所在的工作节点的kubelet通信所致
6.ImgPullErr:镜像拉取失败
7.Containercreating:容器创建中
初始化容器
1.k8s的初始化容器(initContainer)优先级都是高于主容器(container)的。无论容器写在初始化容器前还是写在初始化容器后,会最先执行的都是初始化容器。只有初始化容器执行成功后才可以启动主容器。
2.初始化容器的应用场景应该是多pod。比如:mysql和业务分开两个pod。此时,业务pod添加初始化容器,初始化容器执行telnet,检查mysql是否启动了。若mysql启动,则业务pod启动;否则业务pod等待mysql启动。
定义pod-initcontainer-demo01.yml
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod-initcontainer
namespace: mayikt-sit
spec:
containers:
- name: mayikt-main-container
image: nginx:1.17.9
ports:
- name: nginx-port
containerPort: 80
initContainers:
- name: mayikt-mysql
image: busybox:1.30
command: [ "/bin/sh","-c","sleep 40;"]
- name: mayikt-redis
image: busybox:1.30
busybox:1.30启动成功之后 是会立即停止40S 之后这个容器才会停止
当我们启动mayikt-main-container 容器 必须等待 初始化容器 mayikt-mysql 和mayikt-redis 启动完成并且容器结束之后,才可以启动mayikt-main-container
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f pod-initcontainer-demo01.yml
kubectl describe pods -n mayikt-sit
执行命令:kubectl describe pods -n mayikt-sit mayikt-mysql启动成功之后 40s 结束容器 启动 mayikt-redis
等待mayikt-redis容器启动成功结束之后,开始开动我们的主容器。
执行:kubectl get pods -n mayikt-sit 有两个初始化容器未启动完成
kubectl describe pods -n mayikt-sit 开始启动nginx容器
在查看初始化容器 mayikt-redis、mayikt-mysql
Terminated 结束了
再次查询 主容器启动成功了
kubectl get pods -n mayikt-sit
钩子函数
k8s在主容器的启动之后和停止之前提供了两个钩子函数
1.post-start: 容器创建之后执行(相关命令),如果失败了则会自动重启容器, 容器创建后立即执行,注意由于是异步执行,它无法保证一定在 ENTRYPOINT 之前运行。如果失败,容器会被杀死,并根据 RestartPolicy 决定是 否重启
2.pre-stop :容器终止之前执行(相关命令) 例如 杀死进程等 容器终止前执行,常用于资源清理。执行完成之后容器将成功终止,如果失败,容器同样也会被杀死。在其完成之前 会阻塞删除容器的操作
钩子的回调函数支持三种方式
1.Exec命令 执行Exec命令
spec:
containers:
- name: main-container
image: nginx:1.17.1
lifecycle:
postStart:
exec: #容器创建之后执行(相关命令)修改nginx 页面
command: ["/bin/sh","-c","echo mayikt > /usr/share/nginx/html/index.html"]
preStop:
exec: #容器停止之后 执行停止nginx服务
command: [" /usr/sbin/nginx","-s" , "quit" ]
2.TCPSocket: 发送TCPSocket
lifecycle:
postStart:
tcpSocket:
port: 8080
3.HTTPGet: 发送http请求
lifecycle:
postStart:
httpGet:
path: /init # URI地址
port: 80 # 端口号
host: 192.168.110.1 # 主机地址
scheme: HTTP # 支持的协议,http或https
# http://192.168.110.1/init
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f pod-initcontainer-demo01.yml
kubectl describe pods -n mayikt-sit
apiVersion: v1
kind: Pod
metadata:
name: mayikt-nginx-pod
namespace: mayikt-sit
spec:
containers:
- name: main-container
image: nginx:1.17.9
lifecycle:
postStart:
exec: #容器创建之后执行(相关命令)修改nginx 页面
command: ["/bin/sh","-c","echo mayikt > /usr/share/nginx/html/index.html"]
preStop:
exec: #容器停止之后 执行停止nginx服务
command: [" /usr/sbin/nginx","-s" , "quit" ]
curl 172.17.0.4
容器探测
lvs(k8s-service)+keepalived(心跳)
k8s提供了livenessProbe(可用性探针)和readinessProbe(就绪性探针)对容器的健康性进行检测,类似心跳机制
判断我们应用实例是否存活 如果是为宕机状态 则自动重启,同时如果发现该pod无法接受请求 则service不会转发到该pod上执行。
1.存活探针(可用性探针): 用于检测容器实例当前是否处于正常运行的状态,如果不是为运行状态,k8s则会重启容器;
2.就绪探针readinessProbe(就绪性探针): 就绪性探针,用于检测应用实例当前是否可以接收请求,如果不能接受实例,k8s不会转发到该实例
其实非常好理解,livenessProbe 判断是否 容器是否重启、readinessProbe 判断是否路由转发
支持三种探测方式
1.Exec命令 在容器内执行一次命令,如果命令执行的退出码为0,则认为程序正常,否则不正常
2.TCPSocket: 会尝试访问一个用户指定的容器的端口,如果能够成功建立连接 则认为正常,否则认为不正常
3.HTTPGet: 调用容器内Web系统的url,如果http状态码是在200和399之间,则认为程序正常,否则不正常
Exec命令
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f pod-initcontainer-demo01.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
ports:
- name: nginx-port
containerPort: 80
livenessProbe: ##存活探针(可用性探针)
exec: #执行一个查看文件的命令
command: ["/bin/cat" ,"/tmp/mayikt.txt"]
执行命令 显示主容器启动失败,重启了四次
kubectl describe pods -n mayikt-sit
修改为 执行pwd 没有任何问题则不会重启
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
ports:
- name: nginx-port
containerPort: 80
livenessProbe: ##存活探针(可用性探针)
exec: #执行一个pwd
command: ["/bin/pwd" ,"/"]
kubectl get pods -n mayikt-sit
TCPSocket
会尝试访问一个用户指定的容器的端口,如果能够成功建立连接 则认为正常,否则认为不正常
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f pod-initcontainer-demo01.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
ports:
- name: nginx-port
containerPort: 80
livenessProbe: ##存活探针(可用性探针)
tcpSocket: ## 底层会尝试访问容器ip:8080
port: 8080
kubectl describe pods -n mayikt-sit
Liveness probe failed: dial tcp 172.17.0.4:8080: connect: connection refused
kubectl get pods -n mayikt-sit
修改成正确的
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
ports:
- name: nginx-port
containerPort: 80
livenessProbe: ##存活探针(可用性探针)
tcpSocket: ## 底层会尝试访问容器ip:80
port: 80
就ok没有问题啦
HTTPGet
调用容器内Web系统的url,如果http状态码是在200和399之间,则认为程序正常,否则不正常----实际开发中 返回json数据 端口—200和399 500
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
livenessProbe:
httpGet: #访问指定的scheme://host:port/path
scheme: HTTP #支持的协议,http或者https
port: 80 #端口号
path: /mayikt #URI地址 该地址不存在 会报错404
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f pod-initcontainer-demo01.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
kubectl describe pods -n mayikt-sit
Warning Unhealthy 2s kubelet, node2 Liveness probe failed: HTTP probe failed with statuscode: 404
我们在node2节点 访问 curl 172.17.0.4/mayikt
kubectl get pods -n mayikt-sit 查看重启容器次数
修改成正确的
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
livenessProbe:
httpGet: #访问指定的scheme://host:port/path
scheme: HTTP #支持的协议,http或者https
port: 80 #端口号
path: / #URL地址 该地址不存在 会报错404
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f pod-initcontainer-demo10.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
ok 没有报错啦
探测时间
容器探测原理本身就是心跳策略
- initialDelaySeconds # 容器启动后 等待多少秒 开始执行第一次探测
- timeoutSeconds # 探测超时时间。默认1秒,最小1秒
- periodSeconds # 执行探测的频率,默认是10秒,最小1秒
4.failureThreshold # 连续探测失败多少次才被认定为失败、默认是3,最小值是1
5.successThreshold # 连续探测成功多少次才被认定为成功,默认是1
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
livenessProbe:
httpGet: #访问指定的scheme://host:port/path
scheme: HTTP #支持的协议,http或者https
port: 80 #端口号
path: /mayikt #URI地址 该地址不存在 会报错404
initialDelaySecands: 10 #容器启动后10s开始探测
failureThreshold: 2 ##探测2次认为是失败
restartPolicy: Never #设置重启策略为Never 无论状态如何 不会重启
总结:
初始化容器 对pod启动顺序做一个编排 底层写脚本 脚本
钩子函数 容器停止之前或者容器启动成功之后 走回调的方法 (执行脚本、发送tcp、发送http请求)
容器探测 心跳策略 如果容器宕机了自动重启 重启策略定义(执行脚本、发送tcp、发送http请求)
重启策略
我们的重启策略有三种:
1.Always:出现问题时 自动重启该容器,默认方式。
2.OnFailure :容器终止运行且退出码不为0时重启
3.Never :不论状态为何,都不重启该容器
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f pod-initcontainer-demo01.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
livenessProbe:
httpGet: #访问指定的scheme://host:port/path
scheme: HTTP #支持的协议,http或者https
port: 80 #端口号
path: / #URI地址 该地址不存在 会报错404
restartPolicy: Never #设置重启策略为Never 无论状态如何 不会重启
pod调度策略
默认的情况下,Scheduler计算出一个Pod运行在那个Node节点上,我们也可以直接指定该pod运行在那个node节点上。
1.自动调度:是由Scheduler自动计算的 默认
default-scheduler Successfully assigned mayikt-sit/mayikt-sit-pod to node2
2.定向调度: 通过label 标签指定NodeSelector 或者 NodeName直接指定 该pod运行在那个工作节点上
3.(反)亲和性调度: NodeAffinity、Podffinity、 PodAntiAffinity
4.污点(容忍)调度: Taints、 Toleration
定向调度
1.直接指定 node节点
2.根据标签选择器 来进行决定
根据NodeName 直接定位到具体的 工作节点
cat /etc/hosts
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-dispatch.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
yml相关配置:
apiVersion: v1
kind: Pod
metadata:
name: mayikt-sit-pod
namespace: mayikt-sit
spec:
containers:
- name: nginx-container
image: nginx:1.17.9
nodeName: node2 #指定该pod运行在node1 节点
执行该配置文件 发现我们的 mayikt-sit-pod 运行在 node2 节点。
NodeSelector
1.需要给node节点加上标签,让后运行pod指定标签 就可以将该pod运行在 标签对应上的Node节点上
我们可以根据标签来实现调度
kubectl get nodes --show-labels
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl label nodes node1 nodev=v1
kubectl label nodes node2 nodev=v2
kubectl label nodes node2 key=value
1.创建标签
2.查看node节点标签
kubectl get nodes --show-labels
更新标签:kubectl label nodes node2 nodev=v2 --overwrite
2.定义配置文件
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
nodeSelector:
nodev: v2 #指定调度到具有node=v2标签 node节点上
kubectl create -f mayikt-dispatch.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
亲和性调度
概念
亲和性:如果有两个pod频繁交互,亲和性让两个pod的尽可能的靠近,这样可以减少因网络通信而带来的性能损耗资资源。
反亲和性: 例如 nginxpod 集群 为了保证高可用的问题,需要将nginx 集群的pod 分摊不同的noe节点上。
nginx集群的时候 反亲和性
硬策略: 通过指定的规则,如果没有找到具体运行的Node节点 则会报错
软策略: 优先走指定的规则, 如果没有找到具体运行的Node节点 则采用自动随机方式运行在node节点上。
1.nodeAffinity(node亲和性) : pod根据node标签选择器 决定pod运行在那个node节点上
2.podAffinity(pod亲和性): pod根据参照pod标签选择器 解决多个pod运行在同一个node节点上
3.podAntiffinity(pod反亲和性): pod根据参照pod标签选择器 解决多个pod不允许在同一个node节点上
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
affinity: #设置亲和性
nodeAffinity: #亲和性node 设置
requiredDuringSchedulingIgnoredDuringExecution: #硬限制
nodeSelectorTerms:
- matchExpressions: #匹配nodev的值在[v3,v4 ]中的标签 node节点
- key: nodev
operator: In
values: ["v3" , "v4"]
------------------------------------------------------------------------
---------------------------------------------------------------------
affinity: #亲和性设置
nodeAffinity: #设置node亲和性
preferredDuringSchedulingIgnoredDuringExecution: #软限制
- weight: 1
preference:
matchExpressions: #匹配当前node节点标签是否有 ["v5","v6"]
- key: nodev
operator: In
values: ["v5","v6"]
matchFields
matchExpressions 按节点标签列出的节点选择器要求列表(推荐)
key 键
values值(可以直接写数组)
operator关系符支持Exists, DoesNotExist, In, NotIn, Gt, Lt
硬限制
1.查看当前node节点对应的标签
kubectl get nodes --show-labels
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-dispatch.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
执行该配置文件
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
affinity: #设置亲和性
nodeAffinity: #亲和性node 设置
requiredDuringSchedulingIgnoredDuringExecution: #硬限制
nodeSelectorTerms:
- matchExpressions: #匹配nodev的值在[v3,v4 ]中的标签 node节点
- key: nodev
operator: In
values: ["v3" , "v4"]
pod找不到 v3 v4 标签 则报错
修改成正确的
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-dispatch.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
affinity: #设置亲和性
nodeAffinity: #亲和性node 设置
requiredDuringSchedulingIgnoredDuringExecution: #硬限制
nodeSelectorTerms:
- matchExpressions: #匹配nodev的值在[v3,v4 ]中的标签 node节点
- key: nodev
operator: In
values: ["v1" , "v4"]
kubectl describe pods -n mayikt-sit 调度到node1节点
软限制
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-dispatch.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
affinity: #亲和性设置
nodeAffinity: #设置node亲和性
preferredDuringSchedulingIgnoredDuringExecution: #软限制
- weight: 1
preference:
matchExpressions: #匹配当前node节点标签是否有 ["v5","v6"]
- key: nodev
operator: In
values: ["v5","v6"]
发现未匹配找到 v5、v6标签 则走软限制 在可用node随机选择一个。
pod亲和度
1.先创建好 mayikt-pod1 在node节点
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod01
namespace: mayikt-sit
labels:
podinfo: pod01 #设置标签
spec:
containers:
- name: nginx
image: nginx:1.17.9
nodeName: node1 #将mayikt-pod01指定到node1节点上
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod01.yml
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
2.创建mayikt-pod2 运行同一个node节点
kubectl create -f mayikt-pod02.yml
kubectl describe pods -n mayikt-sit
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod02
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
affinity: #亲和性设置
podAffinity: #设置pod亲和性
requiredDuringSchedulingIgnoredDuringExecution: #策略
- labelSelector:
matchExpressions: #匹配podinfo的值在[mayikt-pod03]中的标签
- key: podinfo
operator: In
values: ["mayikt-pod03"]
topologyKey: kubernetes.io/hostname
运行报错 没有找到 mayikt-sit labels mayikt-pod03
修改配置文件
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod02
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
affinity: #亲和性设置
podAffinity: #设置pod亲和性
requiredDuringSchedulingIgnoredDuringExecution: #策略
- labelSelector:
matchExpressions: #匹配podinfo的值在[mayikt-pod03]中的标签
- key: podinfo
operator: In
values: ["pod01"]
topologyKey: kubernetes.io/hostname
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod01.yml
kubectl create -f mayikt-pod02.yml
kubectl describe pods -n mayikt-sit
我们pod1和pod2 都在同一个node节点
kubectl get pod -n mayikt-sit -o wide --show-labels
反亲和性调度
不参照pod 运行在同一个node节点。
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod01.yml
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod01
namespace: mayikt-sit
labels:
podinfo: pod01 #设置标签
spec:
containers:
- name: nginx
image: nginx:1.17.9
nodeName: node1 #将mayikt-pod01指定到node1节点上
kubectl describe pods -n mayikt-sit
kubectl get pods -n mayikt-sit
创建第二个pod
kubectl create -f mayikt-pod02.yml
apiVersion: v1
kind: Pod
metadata:
name: mayikt-pod02
namespace: mayikt-sit
spec:
containers:
- name: nginx
image: nginx:1.17.9
affinity: #亲和性设置
podAntiAffinity: #设置pod反亲和性
requiredDuringSchedulingIgnoredDuringExecution: #策略
- labelSelector:
matchExpressions: #匹配podinfo的值在[mayikt-pod03]中的标签
- key: podinfo
operator: In
values: ["pod01"]
topologyKey: kubernetes.io/hostname
我们pod1和pod2 不在同一个node节点
kubectl get pod -n mayikt-sit -o wide --show-labels
调度污点
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
站在node节点角度 不允许哪些pod 运行在该node节点上 该过程称作为 污点
如果设置了污点 相当于 pod与node节点发生了排斥关系
1.PreferNoSchedule: kubernetes将尽 量避免把Pod调度到具有该污点的Node上,除非没有其他节点可调度
2.NoSchedule: kubernetes将不会把Pod调度到具有该污点的Node上,但不会影响当前Node上已存在的Pod
3.NoExecute: kubernetes将不会把Pod调度 到具有该污点的Node上,同时也会将Node.上已存在的Pod驱离
kubectl delete ns mayikt-sit 同时将175节点停止
pod控制器
1.k8s弹性扩容与缩容原理
2.Deployment设计原理
3.k8s实现滚动更新原理
4.k8s实现动态灵活版本回退
基本概念
Pod控制器是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试进行重启,当根据重启策略无效,则会重新新建pod的资源。
pod控制器有多种类型:
ReplicaSet: 代用户创建指定数量的pod副本数量,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能。
ReplicaSet主要三个组件组成:
(1)用户期望的pod副本数量
(2)标签选择器,判断哪个pod归自己管理
(3)当现存的pod数量不足,会根据pod资源模板进行新建
帮助用户管理无状态的pod资源,精确反应用户定义的目标数量,但是RelicaSet不是直接使用的控制器,而是使用Deployment。
Deployment:工作在ReplicaSet之上,用于管理无状态应用,目前来说最好的控制器。支持滚动更新和回滚功能,还提供声明式配置。
DaemonSet:用于确保集群中的每一个节点只运行特定的pod副本,通常用于实现系统级后台任务。比如ELK服务
特性:服务是无状态的
服务必须是守护进程
Job:只要完成就立即退出,不需要重启或重建。
Cronjob:周期性任务控制,不需要持续后台运行,
StatefulSet:管理有状态应用
ReplicaSet
创建指定数量的pod副本数量,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能,也就是
主要作用是保证一定数量的pod能够正常运行,它会持续监听这些pod的运行状态,一旦pod发生
故障,就会重启或重建
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod-controller01.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: mayikt-rp
namespace: mayikt-sit
spec:
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.9
相关配置文件说明:
kubectl get pod -n mayikt-sit --show-labels
当前以该模板的形式 启动三个不同的pod 镜像是为1.17.9
labels标签 key是为app、value是为nginx-pod
selector: 选择器,pod控制器与pod之间建立联系,采用的Label Selector机制
matchLabels: Labels匹配规则
kubectl get pod -n mayikt-sit --show-labels
kubectl describe pods -n mayikt-sit
第一个nginx:
172.17.0.2 在 node3/192.168.75.177
第二个nginx:
第三个nginx
node1/192.168.75.167
kubectl get pods -n mayikt-sit
查看该 -n mayikt-sit 副本( mayikt-rp):
kubectl get rs mayikt-rp -n mayikt-sit -o wide
弹性扩容
kubectl edit rs rs名称 -n 命名空间
kubectl edit rs mayikt-rp -n mayikt-sit
进行编辑 修改成6
在保存:
kubectl describe pods -n mayikt-sit
kubectl get rs mayikt-rp -n mayikt-sit -o wide
kubectl get pods -n mayikt-sit
弹性缩容
kubectl edit rs rs名称 -n 命名空间
kubectl edit rs mayikt-rp -n mayikt-sit
kubectl describe pods -n mayikt-sit
kubectl get rs mayikt-rp -n mayikt-sit -o wide
kubectl get pods -n mayikt-sit
通过命令的形式
kubectl scale rs mayikt-rp --replicas=2 -n mayikt-sit
更新镜像
设计灰度发布、滚动发布
kubectl edit rs rs名称 -n 命名空间
kubectl edit rs mayikt-rp -n mayikt-sit
kubectl get rs mayikt-rp -n mayikt-sit -o wide
删除副本
kubectl delete rs mayikt-rp -n mayikt-sit
k8s删除ReplicaSet前,会将ReplicaSet的replicasclear调整为0,等待所有的Pod被删除后,在执行RS对象的删除。
kubectl get pods -n mayikt-sit
或者通过:kubectl delete -f mayikt-pod-controller01.yml 来删除
Deployment
Deployment为Pod和Replica Set(下一代Replication Controller)提供声明式更新。
只需要在 Deployment 中描述想要的目标状态是什么,Deployment controller 就会帮您将 Pod 和ReplicaSet 的实际状态改变到您的目标状态。也可以定义一个全新的 Deployment 来创建 ReplicaSet 或者删除已有的 Deployment 并创建一个新的来替换。
1.继承ReplicaSet的所有功能
2.新增滚动更新和版本回退
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod-controller02.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mayikt-deployment
namespace: mayikt-sit
spec:
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.9
kubectl describe pods -n mayikt-sit
kubectl get deploy -n mayikt-sit -o wide
kubectl get pods -n mayikt-sit
弹性扩容与缩容
弹性扩容
我们可以通过命令或者编辑的形式修改
kubectl edit deploy deploy的名称 -n 命名空间名称
kubectl scale deploy deploy的名称 --replicas=副本数 -n 命名空间名称
kubectl scale deploy mayikt-deployment --replicas=6 -n mayikt-sit
kubectl get pods -n mayikt-sit
弹性缩容
kubectl scale deploy mayikt-deployment --replicas=2 -n mayikt-sit
kubectl get pods -n mayikt-sit
更新镜像
Deployment 支持两种方式修改镜像 分别是重新建更新和滚动更新(默认)
type策略:
1.Recreate 先杀掉所有已存在的Pod,在创建出新的Pod
2.RollingUpdate(滚动更新) 杀死一部分, 就启动一部分 存在两个版本Pod----版本回退
rollingUpdate:当type为RollingUpdate时生效,用于为RollingUpdate设置参数, 支持两个属性:
maxUnavailable:用来指定在升级过程中不可用Pod的最大数量,默认为25%。
maxSurge:用来指定在升级过程中 可以超过期望的Pod的最大数量,默认为25%。
Deployment管理我们的ReplicaSet 集 不是管理我们的pod
重建更新
我们在修改pod里面 容器对应镜像版本时,都会产生一个新的 副本集
kubectl get rs -n mayikt-sit 方便以后做版本回退或者滚动更新
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
执行:kubectl create -f mayikt-pod-controller03.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mayikt-deployment
namespace: mayikt-sit
spec:
strategy: #策略
type: Recreate #重建更新
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.9
单独开启一个Xshell窗口监听:
kubectl get pods -n mayikt-sit -w
修改镜像版本
kubectl get deploy -n mayikt-sit -o wide
kubectl set image deploy mayikt-deployment nginx=nginx:1.17.8 -n mayikt-sit
kubectl get pods -n mayikt-sit -w
kubectl get deploy -n mayikt-sit -o wide
滚动更新
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
执行:kubectl create -f mayikt-pod-controller04.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mayikt-deployment
namespace: mayikt-sit
spec:
strategy: #策略
type: RollingUpdate #滚动更新
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.9
修改镜像版本
kubectl get deploy -n mayikt-sit -o wide
kubectl set image deploy mayikt-deployment nginx=nginx:1.17.8 -n mayikt-sit
kubectl get pods -n mayikt-sit -w
版本回退
根据指定的版本实现回退
查看历史更新的状态:
kubectl rollout history deploy mayikt-deployment -n mayikt-sit
该错误原因是: kubectl create -f mayikt-pod-controller04.yml 后面没有加上
–record
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-pod-controller04.yml --record
再执行:kubectl rollout history deploy mayikt-deployment -n mayikt-sit
kubectl get rs -n mayikt-sit 当前有一个rs
修改nginx镜像
kubectl get deploy -n mayikt-sit -o wide
kubectl set image deploy mayikt-deployment nginx=nginx:1.17.8 -n mayikt-sit
在查看我们的rs kubectl get rs -n mayikt-sit
我们再执行
查看版本更新的状态:
kubectl rollout status deploy mayikt-deployment -n mayikt-sit
根据指定的版本回退
kubectl rollout history deploy mayikt-deployment -n mayikt-sit
kubectl rollout undo deployment mayikt-deployment --to-revision=1 -n mayikt-sit
查看回滚的版本
kubectl get deploy -n mayikt-sit -o wide
版本就变成了1.17.9
Horizontal Pod Autoscaler(HPA)
根据pod cpu使用率情况下 动态扩容与缩容,我们需要安装metrics-server可以用来收集集群中的资源使用情况
1.HPA(Horizontal Pod Autoscaler)Pod自动弹性伸缩,K8S通过对Pod中运行的容器各项指标(CPU占用、内存占用、网络请求量)的检测,实现对Pod实例个数的动态新增和减少。
2.早期的kubernetes版本,只支持CPU指标的检测,因为它是通过kubernetes自带的监控系统heapster实现的。
3.到了kubernetes 1.8版本后,heapster已经弃用,资源指标主要通过metrics api获取,这时能支持检测的指标就变多了(CPU、内存等核心指标和qps等自定义指标)
安装metrics-server
1.安装 yum install git -y
2.使用git下载metrics-server
git clone -b v0.3.6 https://github.com/kubernetes-incubator/metrics-server
注意在下载的过程中,可能会容易超时
3.cd metrics-server/deploy/1.8+/ 修改metrics-server-deployment.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: metrics-server
namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: metrics-server
namespace: kube-system
labels:
k8s-app: metrics-server
spec:
selector:
matchLabels:
k8s-app: metrics-server
template:
metadata:
name: metrics-server
labels:
k8s-app: metrics-server
spec:
hostNetwork: true
serviceAccountName: metrics-server
volumes:
# mount in tmp so we can safely use from-scratch images and/or read-only containers
- name: tmp-dir
emptyDir: {}
containers:
- name: metrics-server
image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6
imagePullPolicy: Always
args:
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
volumeMounts:
- name: tmp-dir
mountPath: /tmp
4.在 /usr/local/metrics-server/deploy/1.8+ 目录中执行
kubectl apply -f ./
5.kubectl get pods -n kube-system
如果有metrics-server-6b976979db-dgh7k pod 则说明安装是成功的
6.在执行 kubectl top nodes
如果报错:
error: metrics not available yet 说明metrics-server 还没有启动完成
耐心等待一会 在执行
kubectl top nodes
创建nginx pod
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
创建nginx pod deployment
kubectl run nginx --image=nginx:1.17.9 --requests=cpu=200m -n mayikt-sit
cpu 最小200MHZ
指定deployment service外部访问
kubectl expose deployment nginx --type=NodePort --port=80 -n mayikt-sit
kubectl get deploy,pod,svc -n mayikt-sit
kubectl describe pods -n mayikt-sit
192.168.75.177:32311
创建HPA
mayikt-hpa.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: mayikt-hpa
namespace: mayikt-sit
spec:
minReplicas: 1 # 设定最小pod数量
maxReplicas: 10 # 设定最大pod数量
targetCPUUtilizationPercentage: 2 # cpu使用率 达到2% 开始弹性扩容
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment # 指定要控制的nginx信息
name: nginx
当cpu使用率达到2%时,开始弹性扩容
kubectl create -f mayikt-hpa.yaml
kubectl get hpa -n mayikt-sit
TARGETS /2% 耐心等待
重试: kubectl get hpa -n mayikt-sit
压力测试
打开另外两个窗口
窗口1:
kubectl get pods -n mayikt-sit -w
窗口2:
kubectl get hpa -n mayikt-sit -w
模拟压力测试(httpclient、jmeter、postmen)
yum install httpd-tools -y
ab -n 100 0000 -c 1000 http://192.168.75.177:31503/
在查看窗口1:
cpu使用率瞬间飙高:
在查看容器 迅速在弹性库容
等流量下降 (耐心等待5-10分钟左右)服务器开始缩容
最后只剩下一个pod
Job
Job负责批量处理短暂的一次性任务 (short lived one-off tasks),即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。
Kubernetes支持以下几种Job:
非并行Job:通常创建一个Pod直至其成功结束
固定结束次数的Job:设置.spec.completions,创建多个Pod,直到.spec.completions个Pod成功结束
带有工作队列的并行Job:设置.spec.Parallelism但不设置.spec.completions,当所有Pod结束并且至少一个成功时,Job就认为是成功
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-job01.yml
apiVersion: batch/v1
kind: Job
metadata:
name: mayikt-job
namespace: mayikt-sit
spec:
manualSelector: true
completions: 4 #指定job运行成功Pods的次数。默认值: 1
parallelism: 2 #指定job在任一时刻并发运行Pods的数量 。默认值: 1
selector:
matchLabels:
app: busybox-pod
template:
metadata:
labels:
app: busybox-pod
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox:1.30
command: ["bin/sh","-c","for i in 9 8 7 6 5; do echo $i;sleep 5 ;done" ]
在打开另外窗口:
kubectl get pod -n mayikt-sit -w
修改策略:
completions: 4 #指定job运行成功Pods的次数。默认值: 1
parallelism: 2 #指定job在任一时刻并发运行Pods的数量 。默认值: 1
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-job01.yml
apiVersion: batch/v1
kind: Job
metadata:
name: mayikt-job
namespace: mayikt-sit
spec:
manualSelector: true
completions: 4 #指定job运行成功Pods的次数。默认值: 1
parallelism: 2 #指定job在任一时刻并发运行Pods的数量 。默认值: 1
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox:1.30
command: ["bin/sh","-c","for i in 9 8 7 6 5; do echo $i;sleep 5 ;done" ]
另外窗口:kubectl get pod -n mayikt-sit -w
CronJob
CronJob控制器以Job控制器资源为其管控对象, 可以根据设定的时间点运行我们pod 。
https://cron.qqe2.com/
kubectl delete ns mayikt-sit
kubectl create ns mayikt-sit
kubectl create -f mayikt-job02.yml
concurrencyPolicy:
Allow: 允许Jobs并发运行(默认)
Forbid: 禁止并发运行, 如果上一次运行尚未完成,则跳过下一次运行
Replace:替换,取消当前正在运行的作业并用新作业替换它
schedule: # cron格式的作业调度运行时间点,用于控制任务在什么时间执行
concurrencyPolicy: #并发执行策略,用于定义前一-次作业运行尚未完成时是否以及如何运行后一次的作业
failedJobHistoryLimit: #为失败的任务执行保留的历史记录数,默认为1
successfulJobHistoryLimit: #为成功的任务执行保留的历史记录数,默认为3 startingDeadlineSeconds: #启动作业错误的超时时长
jobTemplate: # job控制器模板,用于为cronjob控制器生成job对象;下面其实就是job的定义
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: mayikt-cronjob
namespace: mayikt-sit
labels:
controller: cronjob
spec:
schedule: "*/1 * * * *"
jobTemplate:
metadata:
spec:
template:
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox:1.30
command: ["bin/sh","-c","for i in 9 8 7 6 5; do echo $i;sleep 5 ;done" ]
linux 中可以通过 crontab -e 来配置定时任务。不过,linux 中的 cron 只能精确到分钟
一分钟后打开另外窗口:
kubectl get pod -n mayikt-sit -w