1.pod调度的策略
2.pod定向调度
3.pod选择器调度
4.亲和度与反亲和度
5.调度污点与容忍策略

pod详解

https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/

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:容器创建中

初始化容器

img

img

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

img

img

等待mayikt-redis容器启动成功结束之后,开始开动我们的主容器。

执行:kubectl get pods -n mayikt-sit 有两个初始化容器未启动完成

img

img

kubectl describe pods -n mayikt-sit 开始启动nginx容器

img

在查看初始化容器 mayikt-redis、mayikt-mysql

img

Terminated 结束了

再次查询 主容器启动成功了

kubectl get pods -n mayikt-sit

img

钩子函数

img

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

img

容器探测

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"] 

执行命令 显示主容器启动失败,重启了四次

img

kubectl describe pods -n mayikt-sit

img

修改为 执行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

img

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-sitimg

Liveness probe failed: dial tcp 172.17.0.4:8080: connect: connection refused

kubectl get pods -n mayikt-sit

img

修改成正确的

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

img

我们在node2节点 访问 curl 172.17.0.4/mayikt

img

kubectl get pods -n mayikt-sit 查看重启容器次数

img

修改成正确的

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 没有报错啦

探测时间

容器探测原理本身就是心跳策略

\1. initialDelaySeconds # 容器启动后 等待多少秒 开始执行第一次探测

\2. timeoutSeconds # 探测超时时间。默认1秒,最小1秒

\3. 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 无论状态如何 不会重启

img

pod调度策略

默认的情况下,Scheduler计算出一个Pod运行在那个Node节点上,我们也可以直接指定该pod运行在那个node节点上。

1.自动调度:是由Scheduler自动计算的 默认

img

default-scheduler Successfully assigned mayikt-sit/mayikt-sit-pod to node2

2.定向调度: 通过label 标签指定NodeSelector 或者 NodeName直接指定 该pod运行在那个工作节点上

3.(反)亲和性调度: NodeAffinity、Podffinity、 PodAntiAffinity

4.污点(容忍)调度: Taints、 Toleration

img

定向调度

1.直接指定 node节点

2.根据标签选择器 来进行决定

img

根据NodeName 直接定位到具体的 工作节点

cat /etc/hosts

img

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节点上

img

我们可以根据标签来实现调度

kubectl get nodes --show-labels

img

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.创建标签

img

2.查看node节点标签

kubectl get nodes --show-labels

img

更新标签: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

img

亲和性调度

概念

亲和性:如果有两个pod频繁交互,亲和性让两个pod的尽可能的靠近,这样可以减少因网络通信而带来的性能损耗资资源。

img

反亲和性: 例如 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

img

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 标签 则报错

img

修改成正确的

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节点

img

软限制

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

img

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

img

运行报错 没有找到 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

img

我们pod1和pod2 都在同一个node节点

kubectl get pod -n mayikt-sit -o wide --show-labels

img

反亲和性调度

不参照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

img

调度污点

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发生

img

故障,就会重启或重建

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

img

第二个nginx:

img

第三个nginx

node1/192.168.75.167

img

kubectl get pods -n mayikt-sit

img

查看该 -n mayikt-sit 副本( mayikt-rp):

kubectl get rs mayikt-rp -n mayikt-sit -o wide

img

弹性扩容

kubectl edit rs rs名称 -n 命名空间

kubectl edit rs mayikt-rp -n mayikt-sit

img

进行编辑 修改成6

img

在保存:

img

img

kubectl describe pods -n mayikt-sit

kubectl get rs mayikt-rp -n mayikt-sit -o wide

kubectl get pods -n mayikt-sit

img

img

弹性缩容

kubectl edit rs rs名称 -n 命名空间

kubectl edit rs mayikt-rp -n mayikt-sit

img

img

kubectl describe pods -n mayikt-sit

kubectl get rs mayikt-rp -n mayikt-sit -o wide

kubectl get pods -n mayikt-sit

img

通过命令的形式

kubectl scale rs mayikt-rp --replicas=2 -n mayikt-sit

img

img

更新镜像

设计灰度发布、滚动发布

kubectl edit rs rs名称 -n 命名空间

kubectl edit rs mayikt-rp -n mayikt-sit

img

img

kubectl get rs mayikt-rp -n mayikt-sit -o wide

img

删除副本

kubectl delete rs mayikt-rp -n mayikt-sit

k8s删除ReplicaSet前,会将ReplicaSet的replicasclear调整为0,等待所有的Pod被删除后,在执行RS对象的删除。

kubectl get pods -n mayikt-sit

img

img

或者通过:kubectl delete -f mayikt-pod-controller01.yml 来删除

Deployment

Deployment为Pod和Replica Set(下一代Replication Controller)提供声明式更新。

只需要在 Deployment 中描述想要的目标状态是什么,Deployment controller 就会帮您将 Pod 和ReplicaSet 的实际状态改变到您的目标状态。也可以定义一个全新的 Deployment 来创建 ReplicaSet 或者删除已有的 Deployment 并创建一个新的来替换。

img

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

img

kubectl get pods -n mayikt-sit

img

弹性扩容与缩容

弹性扩容

我们可以通过命令或者编辑的形式修改

kubectl edit deploy deploy的名称 -n 命名空间名称

kubectl scale deploy deploy的名称 --replicas=副本数 -n 命名空间名称

kubectl scale deploy mayikt-deployment --replicas=6 -n mayikt-sit

img

kubectl get pods -n mayikt-sit

img

弹性缩容

kubectl scale deploy mayikt-deployment --replicas=2 -n mayikt-sit

img

kubectl get pods -n mayikt-sit

img

更新镜像

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 方便以后做版本回退或者滚动更新

img

img

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

img

修改镜像版本

kubectl get deploy -n mayikt-sit -o wide

img

kubectl set image deploy mayikt-deployment nginx=nginx:1.17.8 -n mayikt-sit

img

kubectl get pods -n mayikt-sit -w

img

kubectl get deploy -n mayikt-sit -o wide

img

滚动更新

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

img

kubectl set image deploy mayikt-deployment nginx=nginx:1.17.8 -n mayikt-sit

img

kubectl get pods -n mayikt-sit -w

img

版本回退

根据指定的版本实现回退

查看历史更新的状态:

kubectl rollout history deploy mayikt-deployment -n mayikt-sit

img

该错误原因是: 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

img

在执行:kubectl rollout history deploy mayikt-deployment -n mayikt-sit

img

kubectl get rs -n mayikt-sit 当前有一个rs

img

修改nginx镜像

kubectl get deploy -n mayikt-sit -o wide

kubectl set image deploy mayikt-deployment nginx=nginx:1.17.8 -n mayikt-sit

img

在查看我们的rs kubectl get rs -n mayikt-sit

img

我们在执行

查看版本更新的状态:

kubectl rollout status deploy mayikt-deployment -n mayikt-sit

img

根据指定的版本回退

kubectl rollout history deploy mayikt-deployment -n mayikt-sit

kubectl rollout undo deployment mayikt-deployment --to-revision=1 -n mayikt-sit

img

查看回滚的版本

kubectl get deploy -n mayikt-sit -o wide

版本就变成了1.17.9

img

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

img

2.使用git下载metrics-server

git clone -b v0.3.6 https://github.com/kubernetes-incubator/metrics-server

img

img

注意在下载的过程中,可能会容易超时 建议将我下载好的 img

3.cd metrics-server/deploy/1.8+/ 修改metrics-server-deployment.yaml

📎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

img

4.在 /usr/local/metrics-server/deploy/1.8+ 目录中执行

kubectl apply -f ./

img

5.kubectl get pods -n kube-system

img

如果有metrics-server-6b976979db-dgh7k pod 则说明安装是成功的

6.在执行 kubectl top nodes

如果报错:

img

error: metrics not available yet 说明metrics-server 还没有启动完成

耐心等待一会 在执行

kubectl top nodes

img

创建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

img

kubectl describe pods -n mayikt-sit

192.168.75.177:32311

img

创建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

img

kubectl get hpa -n mayikt-sit

img

TARGETS /2% 耐心等待

重试: kubectl get hpa -n mayikt-sit

img

压力测试

打开另外两个窗口

窗口1:

kubectl get pods -n mayikt-sit -w

img

窗口2:

kubectl get hpa -n mayikt-sit -w

img

模拟压力测试(httpclient、jmeter、postmen)

yum install httpd-tools -y

img

ab -n 100 0000 -c 1000 http://192.168.75.177:31503/

在查看窗口1:

cpu使用率瞬间飙高:

img

在查看容器 迅速在弹性库容

img

等流量下降 (耐心等待5-10分钟左右)服务器开始缩容

img

最后只剩下一个pod

img

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

img

修改策略:

  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

img

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

img

Logo

开源、云原生的融合云平台

更多推荐