k8s Pod简介与探针实现零宕机发布

目录

一、Pod简介

Pod的退出流程

1、什么是Pod

2、定义一个Pod

二、探针、零宕机发布

1、Pod探针

2、Pod探针的检测方式

3、探针检查参数配置

4、startupProbe

5、liveness

6、readiness

7、Pod 优雅关闭


一、Pod简介

Pod的退出流程

  • 管理员 执行的删除操作

  • Pod 的状态为 terminating

  • EndPoint 会删除 对应的 Pod-IP

  • 执行Prestop的指令

1、什么是Pod

Pod是Kubernetes中最小的单元,它由一组、一个或多个容器组成,每个Pod还包含了一个Pause容器,Pause容器是Pod的父容器,主要负责僵尸进程的回收管理,通过Pause容器可以使同一个Pod里面的多个容器共享存储、网络、PID、IPC等。

通过Pod的概念能够方便 管理容器,因为容器不只一种,有多种容器

副本的概念,便捷的扩容与伸缩,资源的管理,Pod使容器之间的通信更为密切(通过Pause镜像),减少端口的资源浪费

2、Pod基础参数解析

apiVersion: v1 # 必选,API的版本号
kind: Pod       # 必选,类型Pod
metadata:       # 必选,元数据
  name: nginx   # 必选,符合RFC 1035规范的Pod名称
  # namespace: default # 可选,Pod所在的命名空间,不指定默认为default,可以使用-n 指定namespace 
  labels:       # 可选,标签选择器,一般用于过滤和区分Pod,根据业务自定义
    app: nginx
    role: frontend # 可以写多个
  annotations:  # 可选,注释列表,可以写多个
    app: nginx1.21  #可以注释一些 Nginx版本
spec:   # 必选,用于定义容器的详细信息
#  initContainers: # 初始化容器,在容器启动之前执行的一些初始化操作
#  - command:
#    - sh
#    - -c
#    - echo "I am InitContainer for init some configuration"
#    image: busybox
#    imagePullPolicy: IfNotPresent
#    name: init-container
  containers:   # 必选,容器列表
  - name: nginx # 必选,符合RFC 1035规范的容器名称
    image: nginx:1.15.2    # 必选,容器所用的镜像的地址
    imagePullPolicy: IfNotPresent     # 可选,镜像拉取策略, IfNotPresent: 如果宿主机有这个镜像,那就不需要拉取了. Always: 总是拉取, Never: 不管是否存储都不拉去
    command: # 可选,容器启动执行的命令 ENTRYPOINT, arg --> cmd
    - nginx 
    - -g
    - "daemon off;"
    workingDir: /usr/share/nginx/html       # 可选,容器的工作目录
#    volumeMounts:   # 可选,存储卷配置,可以配置多个
#    - name: webroot # 存储卷名称
#      mountPath: /usr/share/nginx/html # 挂载目录
#      readOnly: true        # 只读
    ports:  # 可选,容器需要暴露的端口号列表
    - name: http    # 端口名称
      containerPort: 80     # 端口号
      protocol: TCP # 端口协议,默认TCP
    env:    # 可选,环境变量配置列表
    - name: TZ      # 变量名
      value: Asia/Shanghai # 变量的值
    - name: LANG
      value: en_US.utf8
#    resources:      # 可选,资源限制和资源请求限制
#      limits:       # 最大限制设置
#        cpu: 1000m
#        memory: 1024Mi
#      requests:     # 启动所需的资源
#        cpu: 100m
#        memory: 512Mi
#    startupProbe: # 可选,检测容器内进程是否完成启动。注意三种检查方式同时只能使用一种。
#      httpGet:      # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。
#            path: /api/successStart # 检查路径
#            port: 80
#    readinessProbe: # 可选,健康检查。注意三种检查方式同时只能使用一种。
#      httpGet:      # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。
#            path: / # 检查路径
#            port: 80        # 监控端口
#    livenessProbe:  # 可选,健康检查
      #exec:        # 执行容器命令检测方式
            #command: 
            #- cat
            #- /health
    #httpGet:       # httpGet检测方式
    #   path: /_health # 检查路径
    #   port: 8080
    #   httpHeaders: # 检查的请求头
    #   - name: end-user
    #     value: Jason 
#      tcpSocket:    # 端口检测方式
#            port: 80
#      initialDelaySeconds: 60       # 初始化时间
#      timeoutSeconds: 2     # 超时时间
#      periodSeconds: 5      # 检测间隔
#      successThreshold: 1 # 检查成功为2次表示就绪
#      failureThreshold: 2 # 检测失败1次表示未就绪
#    lifecycle:
#      postStart: # 容器创建完成后执行的指令, 可以是exec httpGet TCPSocket
#        exec:
#          command:
#          - sh
#          - -c
#          - 'mkdir /data/ '
#      preStop:
#        httpGet:      
#              path: /
#              port: 80
      #  exec:
      #    command:
      #    - sh
      #    - -c
      #    - sleep 9
  restartPolicy: Always   # 可选,默认为Always,容器故障或者没有启动成功,那就自动该容器,Onfailure: 容器以不为0的状态终止,自动重启该容器, Never:无论何种状态,都不会重启
  #nodeSelector: # 可选,指定Node节点
  #      region: subnet7
#  imagePullSecrets:     # 可选,拉取镜像使用的secret,可以配置多个
#  - name: default-dockercfg-86258
#  hostNetwork: false    # 可选,是否为主机模式,如是,会占用主机端口
#  volumes:      # 共享存储卷列表
#  - name: webroot # 名称,与上述对应
#    emptyDir: {}    # 挂载目录
#        #hostPath:              # 挂载本机目录
#        #  path: /etc/hosts
 
  

二、探针、零宕机发布

1、Pod探针

实现 零宕机 上线应用

  • StartupProbe:k8s1.16版本后新加的探测方式,用于判断容器内应用程序是否已经启动。如果配置了startupProbe,就会先禁止其他的探测,直到它成功为止,成功后将不在进行探测。

  • LivenessProbe:用于探测容器是否运行,如果探测失败,kubelet会根据配置的重启策略进行相应的处理。若没有配置该探针,默认就是success。

  • ReadinessProbe:一般用于探测容器内的程序是否健康,它的返回值如果为success,那么久代表这个容器已经完成启动,并且程序已经是可以接受流量的状态。

2、Pod探针的检测方式

  • ExecAction:在容器内执行一个命令,如果返回值为0,则认为容器健康。

livenessProbe:
  exec:
    command:
    - pgrep
    - nginx
  • TCPSocketAction:通过TCP连接检查容器内的端口是否是通的,如果是通的就认为容器健康。

livenessProbe:
  tcpSocket:
    port: 80
  • HTTPGetAction:通过应用程序暴露的API地址来检查程序是否是正常的,如果状态码为200~400之间,则认为容器健康。

linvenessProbe:
  httpGet:
    path: /index.html
    port: 80
  • 在公司,开发人员需要暴露该服务的两个健康检查API接口,如果测试两个API接口通,代表容器正常运行,不会去误停容器。

3、探针检查参数配置

探针的参数

  • initialDelaySeconds: 3

    • 容器的初始化时长,用于容器中的服务初始化时间较长的场景

    • 合理使用初始化时长,避免容器中的应用应初始化时长被探针检测失败

  • timeoutSeconds: 2

    • 超时时长,检测一个容器中的服务,超时2秒,认定检测失败

  • periodSeconds: 2

    • 当检测失败后,每隔 2 秒检测一次

  • successThreshold: 1

    • 检测成功的次数,检测1次成功认定该容器ready

  • failureThreshold: 2

    • 检测失败的次数,有两次检测失败,认定该容器 NotReady

检测失败的重启时长

  • 容器初始化检测失败的时长,唯一的区别就是加上容器初始化时长

    • { ( timeoutSecounds + periodSeconds ) * failureThreshold } + initialDelaySeconds

    • { (2+2) * 2} + 3 = 11s

  • 容器启动之后检测的方式

    • ( timeoutSecounds + periodSeconds ) * failureThreshold

    • {(2+2) * 2 = 8s

初始化时间,不建议设置太长,滚动发布受影响 ​ 
# initialDelaySecond: 60   

超时时间,命令去GET页面的超时时间 ​ 
# timeoutSeconds: 2   

检测间隔,每5秒检测一次 ​ 
# periodSeconds: 5   

检查成功为1次表示就绪,检测失败2次表示未就绪 ​ ​ 
# successThreshold: 1 
# failureThreshold: 2 

检测失败的重启时间:(2+5)* 2 = 14 s 所以检测失败次数不建议设置太大

Prestop:先去请求eureka接口,把自己的IP地址和端口号,进行下线,eureka从注册表中删除该应用的IP地址。然后容器进行sleep 90;kill pgrep java

注意:

在生产环境中,一定要合理设置探针检查的参数

假如一个Java程序的初始化时间为90s,我们没有合理设置探测参数,这样会造成,初始化时间没有给到,后面的检查又失败,失败后Pod又被kubelet干掉,又重启,重启之后又初始化,无限循环,这样对业务造成的影响非常大

所以就有新的一种探针模式的增加 --> startupProbe

4、startupProbe

原理:在1.16+版本后,为了防止程序的初始化时间的过长,导致的Pod被检测失败与无限次的重启,设置startupProbe后,程序会在初始化时,先进行startupProbe的检测,检测期间会将其他的两种检测方式进行禁用。只执行一次,自动退出。

4.1、进行测试

[root@k8s-master01 k8s-day01]# vim pod-Probe.yaml
apiVersion: v1 # 必选,API的版本号
kind: Pod       # 必选,类型Pod
metadata:       # 必选,元数据
  name: nginx   # 必选,符合RFC 1035规范的Pod名称
  # namespace: default # 可选,Pod所在的命名空间,不指定默认为default,可以使用-n 指定namespace 
  labels:       # 可选,标签选择器,一般用于过滤和区分Pod,根据业务自定义
    app: nginx
    role: frontend # 可以写多个
  annotations:  # 可选,注释列表,可以写多个
    app: nginx1.19      #可以注释一些 Nginx版本
spec:   # 必选,用于定义容器的详细信息
  nodeSelector:
    kubernetes.io/hostname: k8s-node01
  containers:   # 必选,容器列表
  - name: nginx # 必选,符合RFC 1035规范的容器名称
    image: daocloud.io/library/nginx:latest    # 必选,容器所用的镜像的地址
    imagePullPolicy: IfNotPresent     # 可选,镜像拉取策略, IfNotPresent: 如果宿主机有这个镜像,那就不需要拉取了. Always: 总是拉取, Never: 不管是否存储都不拉去
    command: # 可选,容器启动执行的命令 ENTRYPOINT, arg --> cmd
    - nginx 
    - -g
    - "daemon off;"
    workingDir: /usr/share/nginx/html       # 可选,容器的工作目录
    ports:  # 可选,容器需要暴露的端口号列表
    - name: http    # 端口名称
      containerPort: 80     # 端口号
      protocol: TCP # 端口协议,默认TCP
    env:    # 可选,环境变量配置列表
    - name: TZ      # 变量名
      value: Asia/Shanghai # 变量的值
    - name: LANG
      value: en_US.utf8
    startupProbe: # 可选,检测容器内进程是否完成启动。注意三种检查方式同时只能使用一种。
      httpGet:      # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。
            path: /api/successStart # 检查路径
            port: 80            
  restartPolicy: Always   # 可选,默认为Always,容器故障或者没有启动成功,那就自动该容器,Onfailure: 容器以不为0的状态终止,自动重启该容器, Never:无论何种状态,都不会重启
​

[root@k8s-master01 k8s-day01]# kubectl apply -f  pod-Probe.yaml 
pod/nginx created
​
[root@k8s-master01 k8s-day01]# kubectl get pod 
NAME                            READY   STATUS        RESTARTS   AGE
nginx                           0/1     Running       0          9s
​
[root@k8s-master01 k8s-day01]# kubectl get pod 
NAME                            READY   STATUS        RESTARTS   AGE
nginx                           0/1     Running       2          3m
​                                                    # 重启2次了
#可以看,nginx的Pod并未ready,一直在重启

4.2、解析报错信息

[root@k8s-master01 k8s-day01]# kubectl describe pod nginx | grep -A10 "Events"
Events:
  Type     Reason     Age                     From               Message
  ----     ------     ----                    ----               -------
  Normal   Scheduled  7m38s                   default-scheduler  Successfully assigned default/nginx to k8s-node01
  Normal   Pulled     3m56s (x4 over 7m38s)   kubelet            Container image "daocloud.io/library/nginx:latest" already present on machine
  Normal   Created    3m56s (x4 over 7m38s)   kubelet            Created container nginx
  Normal   Started    3m55s (x4 over 7m38s)   kubelet            Started container nginx
  Warning  Unhealthy  3m55s (x10 over 7m35s)  kubelet            Startup probe failed: HTTP probe failed with statuscode: 404    # 注意看这里,探针检测失败
  Normal   Killing    2m35s (x4 over 6m32s)   kubelet            Container nginx failed startup probe, will be restarted
  

注意:从报错的信息看,HTTP probe 检测失败,主要是因为 "path: /api/successStart",nginx网站并没有/api/successStart该路径, 我们可以加入 TcpSocker 对nginx进行Tcp方面的探测

4.3、进行优化,添加 TcpSocker

[root@k8s-master01 k8s-day01]# vim pod-Probe.yaml
#进行注释与添加
startupProbe: # 可选,检测容器内进程是否完成启动。注意三种检查方式同时只能使用一种。
    #  httpGet:      # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。
    #        path: /api/successStart # 检查路径
    #        port: 80
      tcpSocket:
        port: 80
[root@k8s-master01 k8s-day01]# kubectl apply -f pod-Probe.yaml 
pod/nginx created
​
[root@k8s-master01 k8s-day01]# kubectl get pod
NAME                            READY   STATUS        RESTARTS   AGE
nginx                           1/1     Running       0          2m14s
​
[root@k8s-master01 k8s-day01]# kubectl describe pod nginx | grep -A10 "^Event"
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  3m24s  default-scheduler  Successfully assigned default/nginx to k8s-node01
  Normal  Pulled     3m24s  kubelet            Container image "daocloud.io/library/nginx:latest" already present on machine
  Normal  Created    3m24s  kubelet            Created container nginx
  Normal  Started    3m24s  kubelet            Started container nginx

:可以看到,Pod已经重新恢复,主要是 tcpSocket 检测 80端口 成功,nginx默认80端口

5、liveness

注意:一定要使用接口级的健康检查 /path /index.html.........,尽量少使用命令去检查 pgrep nginx

apiVersion: v1 # 必选,API的版本号
kind: Pod       # 必选,类型Pod
metadata:       # 必选,元数据
  name: nginx   # 必选,符合RFC 1035规范的Pod名称
  # namespace: default # 可选,Pod所在的命名空间,不指定默认为default,可以使用-n 指定namespace 
  labels:       # 可选,标签选择器,一般用于过滤和区分Pod,根据业务自定义
    app: nginx
    role: frontend # 可以写多个
  annotations:  # 可选,注释列表,可以写多个
    app: nginx1.21      #可以注释一些 Nginx版本
spec:   # 必选,用于定义容器的详细信息
  nodeSelector:
    kubernetes.io/hostname: k8s-node01
  containers:   # 必选,容器列表
  - name: nginx # 必选,符合RFC 1035规范的容器名称
    image: daocloud.io/library/nginx:latest    # 必选,容器所用的镜像的地址
    imagePullPolicy: IfNotPresent     # 可选,镜像拉取策略, IfNotPresent: 如果宿主机有这个镜像,那就不需要拉取了. Always: 总是拉取, Never: 不管是否存储都不拉去
    command: # 可选,容器启动执行的命令 ENTRYPOINT, arg --> cmd
    - nginx 
    - -g
    - "daemon off;"
    ports:  # 可选,容器需要暴露的端口号列表
    - name: http    # 端口名称
      containerPort: 80     # 端口号
      protocol: TCP # 端口协议,默认TCP
    env:    # 可选,环境变量配置列表
    - name: TZ      # 变量名
      value: Asia/Shanghai # 变量的值
    - name: LANG
      value: en_US.utf8
    startupProbe: # 可选,检测容器内进程是否完成启动。注意三种检查方式同时只能使用一种。
    #  httpGet:      # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。
    #        path: /api/successStart # 检查路径
    #        port: 80
      tcpSocket:
        port: 80
    readinessProbe: # 可选,健康检查。注意三种检查方式同时只能使用一种。
      httpGet:      # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。
            path: / # 检查路径
            port: 80        # 监控端口
#-------------------------------------------------
    livenessProbe:  # 可选,健康检查
      #exec:        # 执行容器命令检测方式
            #command: 
            #- cat
            #- /health
      httpGet:       # httpGet检测方式
         path: /index.html # 检查路径
         port: 80
    #   httpHeaders: # 检查的请求头
    #   - name: end-user
    #     value: Jason 
#-------------------------------------------------
      initialDelaySeconds: 3    # 初始化时间
      timeoutSeconds: 2     # 超时时间
      periodSeconds: 2      # 检测间隔
      successThreshold: 1 # 检查成功为2次表示就绪
      failureThreshold: 2 # 检测失败1次表示未就绪

  restartPolicy: Always 

6、readiness

  • readiness 美 /'rɛdɪnəs/ 英 /'redɪnəs/ n. 敏捷,迅速;准备就绪;愿意

解析:自定义 监控项对容器启动时的监控,如果监测失败,不会去重启容器,不会停止容器

只会 限制 服务的 进出流量,用户只能通过 Pod-IP进行访问,无法从Cluster-IP、NodePort-IP进行访问。

1、报错演示

[root@k8s-master01 k8s-day01]# vim pod-Probe.yaml

apiVersion: v1 # 必选,API的版本号
kind: Pod       # 必选,类型Pod
metadata:       # 必选,元数据
  name: nginx   # 必选,符合RFC 1035规范的Pod名称
  # namespace: default # 可选,Pod所在的命名空间,不指定默认为default,可以使用-n 指定namespace 
  labels:       # 可选,标签选择器,一般用于过滤和区分Pod,根据业务自定义
    app: nginx
    role: frontend # 可以写多个
  annotations:  # 可选,注释列表,可以写多个
    app: nginx1.21      #可以注释一些 Nginx版本
spec:   # 必选,用于定义容器的详细信息
  nodeSelector:
    kubernetes.io/hostname: k8s-node01
  containers:   # 必选,容器列表
  - name: nginx # 必选,符合RFC 1035规范的容器名称
    image: daocloud.io/library/nginx:latest    # 必选,容器所用的镜像的地址
    imagePullPolicy: IfNotPresent     # 可选,镜像拉取策略, IfNotPresent: 如果宿主机有这个镜像,那就不需要拉取了. Always: 总是拉取, Never: 不管是否存储都不拉去
    command: # 可选,容器启动执行的命令 ENTRYPOINT, arg --> cmd
    - nginx 
    - -g
    - "daemon off;"
    workingDir: /usr/share/nginx/html       # 可选,容器的工作目录
    ports:  # 可选,容器需要暴露的端口号列表
    - name: http    # 端口名称
      containerPort: 80     # 端口号
      protocol: TCP # 端口协议,默认TCP
    env:    # 可选,环境变量配置列表
    - name: TZ      # 变量名
      value: Asia/Shanghai # 变量的值
    - name: LANG
      value: en_US.utf8
#"---------------------------------------------------------------------------"
    readinessProbe: # 可选,健康检查。注意三种检查方式同时只能使用一种。
      httpGet:      # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。
            path: /a.html # 检查路径,该路径不存在
            port: 80        # 监控端口
#"---------------------------------------------------------------------------"
      initialDelaySeconds: 3    # 初始化时间
      timeoutSeconds: 2     # 超时时间
      periodSeconds: 2      # 检测间隔
      successThreshold: 1 # 检查成功为2次表示就绪
      failureThreshold: 2 # 检测失败1次表示未就绪
      preStop:  #容器关闭之前执行的命令
  restartPolicy: Always


[root@k8s-master01 k8s-day01]# vim nginx-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc

spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: 80    # 映射端口,nginx服务为80端口,如果mysql就3306
    nodePort: 30080   # 映射到外部的端口,可以在外部浏览器访问 Node-IP:30080
  - name: https       # SSL
    port: 443
    targetPort: 443
    nodePort: 30443
  selector:            # 上方的Nginx设置的 Labels
    app: nginx
[root@k8s-master01 k8s-day01]# kubectl apply -f pod-Probe.yaml 
pod/nginx created

[root@k8s-master01 k8s-day01]# kubectl get pod -o wide
NAME              READY   STATUS        RESTARTS   AGE     IP               NODE           
nginx             0/1     Running       0          5m7s    172.17.125.11    k8s-node01  

[root@k8s-master01 k8s-day01]# kubectl apply -f nginx-svc.yaml 
service/nginx-svc configured
[root@k8s-master01 k8s-day01]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
kubernetes   ClusterIP   10.96.0.1                443/TCP                      3d20h
nginx-svc    NodePort    10.106.106.114           80:30080/TCP,443:30443/TCP   3d15h
                                           # 10.106.106.114:80 -> 192.168.178.54:30080
                                                                 (部署Pod的Node-IP)

查看报错日志信息:
[root@k8s-master01 k8s-day01]# kubectl describe pod nginx | grep -A10 "Event"
Events:
  Type     Reason     Age                     From               Message
  ----     ------     ----                    ----               -------
  Normal   Scheduled  3m24s                   default-scheduler  Successfully assigned default/nginx to k8s-node01
  Normal   Pulled     3m24s                   kubelet            Container image "daocloud.io/library/nginx:latest" already present on machine
  Normal   Created    3m24s                   kubelet            Created container nginx
  Normal   Started    3m24s                   kubelet            Started container nginx
  Warning  Unhealthy  2m39s (x22 over 3m21s)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 404

2、使用容器内部进行访问,可以看到访问成功:
[root@k8s-master01 k8s-day01]# kubectl exec -it nginx -- sh
# curl -I localhost:80
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 11 Nov 2021 06:07:30 GMT
# curl -I 172.17.125.11:80
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 11 Nov 2021 06:15:05 GMT

3、使用外部、集群IP进行访问进行访问,访问失败,进出流量限制:
[root@k8s-master01 k8s-day01]# curl -I 10.106.106.114:80
curl: (7) Failed connect to 10.106.106.114:80; Connection refused
[root@k8s-master01 k8s-day01]# curl -I 192.168.178.54:30080
curl: (7) Failed connect to 192.168.178.54:30080; Connection refused

2、正确演示

#找到并修改
    readinessProbe: 
      httpGet:      
            path: /index.html # 修改此处即可
            port: 80       
[root@k8s-master01 k8s-day01]# kubectl describe pod nginx | grep -A10 "Event"
Events:
  Type     Reason     Age                     From               Message
  ----     ------     ----                    ----               -------
  Normal   Scheduled  3m24s                   default-scheduler  Successfully assigned default/nginx to k8s-node01
  Normal   Pulled     3m24s                   kubelet            Container image "daocloud.io/library/nginx:latest" already present on machine
  Normal   Created    3m24s                   kubelet            Created container nginx
  Normal   Started    3m24s                   kubelet            Started container nginx
  Warning  Unhealthy  2m39s (x22 over 3m21s)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 404

2、使用容器内部进行访问,可以看到访问成功:
[root@k8s-master01 k8s-day01]# kubectl exec -it nginx -- sh
# curl -I localhost:80
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 11 Nov 2021 06:07:30 GMT
# curl -I 172.17.125.11:80
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 11 Nov 2021 06:15:05 GMT

3、使用外部、集群IP进行访问进行访问,访问失败,进出流量限制:
[root@k8s-master01 k8s-day01]# curl -I 10.106.106.114:80
curl: (7) Failed connect to 10.106.106.114:80; Connection refused
[root@k8s-master01 k8s-day01]# curl -I 192.168.178.54:80
curl: (7) Failed connect to 192.168.178.54:80; Connection refused
[root@k8s-master01 k8s-day01]# kubectl apply -f pod-Probe.yaml 
pod/nginx created
[root@k8s-master01 k8s-day01]# kubectl get pod -o wide
NAME              READY   STATUS        RESTARTS   AGE     IP               NODE           
nginx             1/1     Running       0          18s     172.17.125.12    k8s-node01    

1、使用容器内部访问,访问成功:
[root@k8s-master01 k8s-day01]# kubectl exec -it nginx -- sh
# curl -I  172.17.125.12:80
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 11 Nov 2021 06:40:58 GMT

2、使用容器Cluster-IP、NodePort访问,成功:
[root@k8s-master01 k8s-day01]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
kubernetes   ClusterIP   10.96.0.1                443/TCP                      3d20h
nginx-svc    NodePort    10.106.106.114           80:30080/TCP,443:30443/TCP   3d15h

[root@k8s-master01 k8s-day01]# curl -I 10.106.106.114:80
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 11 Nov 2021 06:42:17 GMT

[root@k8s-master01 k8s-day01]# curl -I 192.168.178.54:30080
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 11 Nov 2021 06:42:37 GMT

7、Pod 优雅关闭

零宕机下线应用

  • 合理使用 proStop,进行容器退出时执行的命令

1、Pod优雅关闭

模式:

  • postStart

    • 容器在启动之前做的一系列指定操作,比如 提前创建 目录、文件、执行脚本等。

  • preStop

    • 容器关闭之后,执行的命令

    • 通常我们会使用该参数进行 Pod 的优雅关闭,实现 零宕机 下线服务

spec:  
  terminationGracePeriods: 90s
  containers:
    lifecycle:
      preStop:  #容器关闭之前执行的命令
        exec:
          command:
          - sh
          - -c
          - sleep 90;kill `pgrep nginx`	
  • 可以看到下方的 yaml 配置 ,nginx 在退出时,执行了睡眠操作,保证容器中的服务 有足够的时间进行下线操作(处理服务关闭之前,接收的服务未进行处理,等待处理完成后,关闭服务,保证数据的完整性)

注意:

  • 我们往往会忽视一个参数,terminationGracePeriodSeconds (容器优雅的关闭的时间间隔)

  • 这参数默认为30秒,就算你不设置, terminationGracePeriodSeconds: 30

再次注意:

  • 如果你想使 容器 进行 90s 的优雅关闭时长,那你的参数应该为 terminationGracePeriodSeconds: 90

    • 加入你设置的 sleep 时长为 90s ,你的参数为 terminationGracePeriodSeconds: 30,那肯定容器只等待30s左右就会关闭,你应该设置参数为 50s,才能保证 sleep 50 运行成功

  • 所以我们在进行容器优雅下线时,要合理使用 preStop 与 该参数

2、效果演示

1️⃣默认情况:terminationGracePeriodSeconds: 30

apiVersion: v1 # 必选,API的版本号
kind: Pod       # 必选,类型Pod
metadata:       # 必选,元数据
  name: nginx   # 必选,符合RFC 1035规范的Pod名称
  # namespace: default # 可选,Pod所在的命名空间,不指定默认为default,可以使用-n 指定namespace 
  labels:       # 可选,标签选择器,一般用于过滤和区分Pod,根据业务自定义
    app: nginx
    role: frontend # 可以写多个
  annotations:  # 可选,注释列表,可以写多个
    app: nginx1.21      #可以注释一些 Nginx版本
spec:   # 必选,用于定义容器的详细信息
  nodeSelector:
    kubernetes.io/hostname: k8s-node01
  containers:   # 必选,容器列表
  - name: nginx # 必选,符合RFC 1035规范的容器名称
    image: daocloud.io/library/nginx:latest    # 必选,容器所用的镜像的地址
    imagePullPolicy: IfNotPresent     # 可选,镜像拉取策略, IfNotPresent: 如果宿主机有这个镜像,那就不需要拉取了. Always: 总是拉取, Never: 不管是否存储都不拉去
    command: # 可选,容器启动执行的命令 ENTRYPOINT, arg --> cmd
    - nginx 
    - -g
    - "daemon off;"
    workingDir: /usr/share/nginx/html       # 可选,容器的工作目录
    ports:  # 可选,容器需要暴露的端口号列表
    - name: http    # 端口名称
      containerPort: 80     # 端口号
      protocol: TCP # 端口协议,默认TCP
    env:    # 可选,环境变量配置列表
    - name: TZ      # 变量名
      value: Asia/Shanghai # 变量的值
    - name: LANG
      value: en_US.utf8
    startupProbe: # 可选,检测容器内进程是否完成启动。注意三种检查方式同时只能使用一种。
      tcpSocket:
        port: 80
    readinessProbe: # 可选,健康检查。注意三种检查方式同时只能使用一种。
      httpGet:      # httpGet检测方式,生产环境建议使用httpGet实现接口级健康检查,健康检查由应用程序提供。
            path: / # 检查路径
            port: 80        # 监控端口
    livenessProbe:  # 可选,健康检查
      httpGet:       # httpGet检测方式
         path: /index.html # 检查路径
         port: 80
      initialDelaySeconds: 3    # 初始化时间
      timeoutSeconds: 2     # 超时时间
      periodSeconds: 2      # 检测间隔
      successThreshold: 1 # 检查成功为2次表示就绪
      failureThreshold: 2 # 检测失败1次表示未就绪
    lifecycle:
      preStop:  #容器关闭之前执行的命令
        exec:
          command:
          - sh
          - -c
#"----------------------------------------------------------------------"
          - sleep 90;kill `pgrep nginx`		#设置 90 秒关闭 容器
#"----------------------------------------------------------------------"
  restartPolicy: Always 
[root@k8s-master01 k8s-day01]# kubectl apply -f pod-Probe.yaml 
pod/nginx created

[root@k8s-master01 k8s-day01]# kubectl get pod
NAME                            READY   STATUS        RESTARTS   AGE
nginx                           1/1     Running       0          15s


[root@k8s-master01 k8s-day01]# time kubectl delete -f pod-Probe.yaml 
pod "nginx" deleted

real	0m36.076s
user	0m0.051s
sys	0m0.031s
#这里可以看到,容器并没有 90 秒退出,默认的 terminationGracePeriodSeconds 为30s

2️⃣修改:terminationGracePeriodSeconds: 90s

spec:   # 必选,用于定义容器的详细信 息
  nodeSelector:
    kubernetes.io/hostname: k8s-node01
# "----------------------------------------------------------------------"
  terminationGracePeriodSeconds: 90		#添加此行,为 90s 进行优雅关闭容器
# "-----------------------------------------------------------------------"
[root@k8s-master01 k8s-day01]# kubectl apply -f pod-Probe.yaml 
pod/nginx created  
  
[root@k8s-master01 k8s-day01]# time kubectl delete -f pod-Probe.yaml 
pod "nginx" deleted

real	1m32.343s	#可以看到 关闭时长为 90s
user	0m0.057s
sys	0m0.022s

你可能感兴趣的:(架构师之路,Kubernetes,kubernetes,docker,容器,云计算,linux)