• 4 pod的状态以及探针类型和方式


    一 Pod的常见状态、pause容和init容器

    1 pod常见的状态

    Unschedulable  #pod不能被调度,kube-scheduler没有匹配到合适的node节点
    PodScheduled  #pod正处于调度中,在kube-schedulerg刚开始调度的时候,还没有将pod分配到指定的node,在筛选出合适的节点后就会更新etcd数据,将pod分配到指定的node
    Pending #正在创建的pod,但是pod中的容器还诶呦完全被创建完成(处于此状态的pod应该检查pod依赖的存储是否有权限挂载等)
    Failed  #pod中有容器启动失败而导致pod工作异常
    Unknown  #由于某种原因无法获得Pod的当前状态,通常是由于pod所在的node节点通信错误
    initialized #所有的pod中的初始化容器已经完成了
    imagePullBackOff #pod所在的node节点下载镜像失败
    Running # pod内部的容器已经被创建并且启动
    Ready  #表示pod中的容器已经可以提供访问服务
    Error # 启动过程中发生错误
    NodeLost #pod所在节点失联
    waiting #pod等待启动
    Terminating # pod正在被销毁
    CrashLoopBackOff  #pod停止,但是kubelet正在将他重启
    invalidlmagename # node节点无法解析镜像名称,导致无法下载
    ImageinspectError #无法校验镜像,镜像不完整导致
    ErrimageNeverPull #策略禁止拉取镜像,镜像中心权限是私有
    RegistryUnavailable #镜像服务器不可用,网络原因或者harbor宕机
    ErrimagePull #镜像拉取出错,超时或者下载被强制终止
    createcontainerconfigerror #不能创建kubelet使用的容器配置
    createcontainerError #创建容器失败
    RuncontainerError  # pod运行失败,容器中没有初始化pid为1的守护进程等
    containersNotlnitialized #pod没有初始化完毕
    containerNotReady #pod 没有准备完毕
    
    containerCreating #pod正在创建中
    podinitializing #pod初始化中
    DockerDaemonNotReady #node节点docker服务没有启动
    NetworkPluginNotReady #网络插件没有启动
    
    

    2 pause容和init容器

    2.1 pause 容器

    pause 容器,又叫infra容器,是Pod的基础容器,镜像体积只有几百kb左右,配置在kubelet中,主要功能是一个pod中多个容器的网络通信。
    infra容器被创建后会初始化network namespace,之后其他容器剧可以加入的infra容器中共享infra容器的网络了。
    一个pod中的两个容器A和bB,那么关系如下:
    1 a容器和B容器能够直接使用localhost通信
    2 a容器和b容器可以看到网卡,ip和端口监听信息。
    3 pod只有一个ip地址,也就是改pod的network,namespace对应的ip地址(由infra容器初始化并创建)
    4 k8s环境中的每个pod有一个独立的ip地址,并且此ip被当前pod中所有容器在内部共享使用。
    5 pod删除后infra容器随机被删除,其ip被回收。
    image

    pause-宿主机的namespace
    image
    然后到Pod所在的宿主机验证网卡
    image
    查看一个pod的Ip,然后去宿主机找到对应的ip
    image

    然后在node节点运行如下命令

    [root@k8s-node1 pause-test-case]# nsenter --net=/run/docker/netns/e8097040db3f ifconfig
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 10.100.36.125  netmask 255.255.255.255  broadcast 10.100.36.125
            ether 0a:e4:27:eb:50:44  txqueuelen 0  (Ethernet)
            RX packets 5  bytes 446 (446.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    

    e8097040db3f 这个就是namespace

    2.2 演示实例:通过docker演示pause,需要准备一个nginx.conf和index.html

    [root@k8s-node1 pause-test-case]# cat nginx.conf 
    error_log stderr;
    events { worker_connections  1024; }
    http {
        access_log /dev/stdout;
        server {
            listen 80 default_server;
            server_name www.mysite.com;
            location / {
              index index.html index.php;
              root /usr/share/nginx/html;
             }
            location ~ \.php$ {
                root           /usr/share/nginx/html;
                fastcgi_pass   127.0.0.1:9000;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                 include        fastcgi_params;
                 }
            }
    }
    

    index.html和index.php
    image
    1 启动一个pause容器

    docker run -d -p80:80 --name pause-container-1 easzlab/pause:3.6
    

    2 启动一个nginx容器,网络使用pause的网络

    docker run -d --name  nginx-container-test -v `pwd`/nginx.conf:/etc/nginx/nginx.conf -v `pwd`/html:/usr/share/nginx/html/ --net=container:pause-container-1 nginx:1.20.0
    

    3启动一个php容器,网络也使用pause的

     docker run -d --name php-test --net=container:pause-container-1 -v `pwd`/html:/usr/share/nginx/html/ php:5.6.40-fpm
    

    访问效果
    image

    image

    2.3 init容器

    2.3.1 init 容器的作用:

    1 可以为业务容器提前准备好业务容器的运行环境,
    2 可以在卞业务容器之前准备好需要的业务数据
    3 检查依赖的服务是否可以访问

    2.3.2 init容器的特点:

    1 一个pod可以有多个业务网容器,还能在有多个init容器,但是每个init容器和业务容器的运行环境都是隔离的
    2 init容器会比业务容器先启动
    3 init 容器运行成功后,才运行业务容器
    4如果一个pod有多个init容器,那么需要从上到下逐个运行并且全部成功,最后才会运行业务容器。
    5 init 容器不支持探针检测,因为初始化完成后退出就再也不运行了

    举例:创建一个nginx的pod,需要初始化网站的数据,这里用centos:7.9.2009 这个镜像来做init的容器

    [root@k8s-master1 init]# cat 1-init-container.yaml 
    kind: Deployment
    #apiVersion: extensions/v1beta1
    apiVersion: apps/v1
    metadata:
      labels:
        app: myserver-myapp 
      name: myserver-myapp-deployment-name
      namespace: myserver
    spec:
      replicas: 1 
      selector:
        matchLabels:
          app: myserver-myapp-frontend
      template:
        metadata:
          labels:
            app: myserver-myapp-frontend
        spec:
          containers:
            - name: myserver-myapp-container
              image: nginx:1.20.0
              #imagePullPolicy: Always
              volumeMounts:
              - mountPath: "/usr/share/nginx/html/myserver"
                name: myserver-data
          initContainers:
            - name: init-web-data
              image: centos:7.9.2009
              command: ['/bin/bash','-c',"for i in `seq 1 10`;do echo '<h1>'$i web page at $(date +%Y%m%d%H%M%S) '<h1>' >> /data/nginx/html/myserver/index.html;sleep 1;done"]
              volumeMounts:
              - mountPath: "/data/nginx/html/myserver"
                name: myserver-data
            - name: change-data-owner
              image: busybox:1.28
              command: ['/bin/sh','-c',"/bin/chmod 644 /data/nginx/html/myserver/* -R"]
              volumeMounts:
              - mountPath: "/data/nginx/html/myserver"
                name: myserver-data
          volumes:
          - name: myserver-data
            hostPath:
              path: /tmp/data/html
    
    ---
    kind: Service
    apiVersion: v1
    metadata:
      labels:
        app: myserver-myapp-service
      name: myserver-myapp-service-name
      namespace: myserver
    spec:
      type: NodePort
      ports:
      - name: http
        port: 80
        targetPort: 80
        nodePort: 30080
      selector:
        app: myserver-myapp-frontend
    
    

    效果如下:
    image

    二 pod的声明周期和探针

    2.1 生命周期

    pod的声明周期,从start后可以配置poststart检查,运行过程中可以配置livenessprobe和readlinessprobe ,最后在stop前可以配置prestop配置

    2.2 探针简介

    探针是由kubelet对容器执行的定期诊断,以保证pod的状态始终处于运行状态,要执行诊断,kubelet调用由容器实现的handler,也称为钩子,有是那种类型的处理程序
    1 Execaction
    在容器内部执行指定命令,如果命令退出时,返回码为0,则认为诊断成功
    2 TcpSocketaction
    对指定端口上的容器ip地址进行tcp检查,如果端口打开,则认为是成功的
    3 HTTPGetAction
    对指定的端口和路径上的容器的ip地址执行httpget请求,如果相应状态码大于等于200且小于400,则认为是成功的。
    HTTP 探针 允许针对 httpGet 配置额外的字段:

    
    host:连接使用的主机名,默认是 Pod 的 IP。也可以在 HTTP 头中设置 “Host” 来代替。
    scheme :用于设置连接主机的方式(HTTP 还是 HTTPS)。默认是 "HTTP"。
    path:/index.html  #访问 HTTP 服务的路径。默认值为 "/"。
    httpHeaders:请求中自定义的 HTTP 头。HTTP 头字段允许重复。
    port:80 #访问容器的端口号或者端口名。如果数字必须在 1~65535 之间。
    

    探针最终的三种结果
    成功
    失败
    未知:诊断失败,因此不会采取任何行动

    2.3 探针类型

    1 startupProbe #启动探针,v1.16引入
    判断容器内的应用程序是否已启动完成。如果配置了启动探测,则会先禁用所有其他的探测,直到startupprobe检查成功为止,如果startupprobe,检查失败,则kubelet将杀死容器,

    2 livenssprobe #存活探针
    检查容器是否正在运行,如果存活探测失败,则kublet会杀死容器,并且容器将受到其重启策略的影响,如果容器不提供存活探针,则默认状态为success,livessprobe用户控制是否重启pod

    3 readinessprobe # 就绪探针
    如果就绪探针检测失败,端点控制器将从与pod匹配的所有的service的端点中删除该pod的ip地址,初始延迟之前的就绪状态默认为failure 失败,如果容器不提供就绪探针,则默认为success,
    readinessprobe用于控制pod是否添加到service里。

    2.3.1 strtupProbe实例

    [root@k8s-master1 probe]# cat 4-startupProbe.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myserver-myapp-frontend-deployment
      namespace: myserver
    spec:
      replicas: 1
      selector:
        matchLabels: #rs or deployment
          app: myserver-myapp-frontend-label
        #matchExpressions:
        #  - {key: app, operator: In, values: [myserver-myapp-frontend,ng-rs-81]}
      template:
        metadata:
          labels:
            app: myserver-myapp-frontend-label
        spec:
          containers:
          - name: myserver-myapp-frontend-label
            image: nginx:1.20.2
            ports:
            - containerPort: 80
            startupProbe:
              httpGet:
                path: /index.html
                port: 80
              initialDelaySeconds: 5 #首次检测延迟5s
              failureThreshold: 3  #从成功转为失败的次数
              periodSeconds: 3 #探测间隔周期
    
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: myserver-myapp-frontend-service
      namespace: myserver
    spec:
      ports:
      - name: http
        port: 81 # k8s之间访问的端口
        targetPort: 80  #容器里的端口
        nodePort: 40012
        protocol: TCP
      type: NodePort
      selector:
        app: myserver-myapp-frontend-label
    
    
    

    2.3.2 三种探针全部加上

    [root@k8s-master1 probe]# cat 5-startupProbe-livenessProbe-readinessProbe.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myserver-myapp-frontend-deployment
      namespace: myserver
    spec:
      replicas: 1
      selector:
        matchLabels: #rs or deployment
          app: myserver-myapp-frontend-label
        #matchExpressions:
        #  - {key: app, operator: In, values: [myserver-myapp-frontend,ng-rs-81]}
      template:
        metadata:
          labels:
            app: myserver-myapp-frontend-label
        spec:
          terminationGracePeriodSeconds: 60
          containers:
          - name: myserver-myapp-frontend-label
            image: nginx:1.20.2
            ports:
            - containerPort: 80
            startupProbe:
              httpGet:
                #path: /monitor/index.html
                path: /index.html
                port: 80
              initialDelaySeconds: 5 #首次检测延迟5s
              failureThreshold: 3  #从成功转为失败的次数
              periodSeconds: 3 #探测间隔周期
            readinessProbe:
              httpGet:
                #path: /monitor/monitor.html
                path: /index.html
                port: 80
              initialDelaySeconds: 5
              periodSeconds: 3
              timeoutSeconds: 5
              successThreshold: 1
              failureThreshold: 3
            livenessProbe:
              httpGet:
                #path: /monitor/monitor.html
                path: /index.html
                port: 80
              initialDelaySeconds: 5
              periodSeconds: 3
              timeoutSeconds: 5
              successThreshold: 1
              failureThreshold: 3
    
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: myserver-myapp-frontend-service
      namespace: myserver
    spec:
      ports:
      - name: http
        port: 81
        targetPort: 80
        nodePort: 40012
        protocol: TCP
      type: NodePort
      selector:
        app: myserver-myapp-frontend-label
    
    
    

    2.4 探针通用配置参数

    initialDelaySeconds:120 # 容器启动后要等待多少秒后才启动存活和就绪探测器, 默认是 0 秒,最小值是 0。
    periodSeconds:60 #执行探测的时间间隔(单位是秒)。默认是 10 秒。最小值是 1。
    timeoutSeconds:5 #探测的超时后等待多少秒。默认值是 1 秒。最小值是 1。
    successThreshold:1 # 探测器在失败后,被视为成功的最小连续成功数。默认值是 1。 存活和启动探测的这个值必须是 1。最小值是 1。
    failureThreshold:3 #当探测失败时,Kubernetes 的重试次数。 对存活探测而言,放弃就意味着重新启动容器。 对就绪探测而言,放弃意味着 Pod 会被打上未就绪的标签。默认值是 3。最小值是 1。
    

    2.5 探针检测方式演示

    1 http类型探针

    [root@k8s-master1 probe]# kubectl apply -f 1-http-Probe.yaml 
    deployment.apps/myserver-myapp-frontend-deployment created
    service/myserver-myapp-frontend-service created
    [root@k8s-master1 probe]# cat 1-http-Probe.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myserver-myapp-frontend-deployment
      namespace: myserver
    spec:
      replicas: 1
      selector:
        matchLabels: #rs or deployment
          app: myserver-myapp-frontend-label
        #matchExpressions:
        #  - {key: app, operator: In, values: [myserver-myapp-frontend,ng-rs-81]}
      template:
        metadata:
          labels:
            app: myserver-myapp-frontend-label
        spec:
          containers:
          - name: myserver-myapp-frontend-label
            image: nginx:1.20.2
            ports:
            - containerPort: 80
            #readinessProbe:
            livenessProbe:
              httpGet:
                #path: /monitor/monitor.html
                path: /index.html
                port: 80
              initialDelaySeconds: 5
              periodSeconds: 3
              timeoutSeconds: 3
              successThreshold: 1
              failureThreshold: 3
    
            readinessProbe:
              httpGet:
                #path: /monitor/monitor.html
                path: /index.html
                port: 80
              initialDelaySeconds: 5
              periodSeconds: 3
              timeoutSeconds: 3
              successThreshold: 1
              failureThreshold: 3
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: myserver-myapp-frontend-service
      namespace: myserver
    spec:
      ports:
      - name: http
        port: 80
        targetPort: 80
        nodePort: 40018
        protocol: TCP
      type: NodePort
      selector:
        app: myserver-myapp-frontend-label
    
    

    2 tcp检查

    [root@k8s-master1 probe]# cat 2-tcp-Probe.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myserver-myapp-frontend-deployment
      namespace: myserver
    spec:
      replicas: 1
      selector:
        matchLabels: #rs or deployment
          app: myserver-myapp-frontend-label
        #matchExpressions:
        #  - {key: app, operator: In, values: [myserver-myapp-frontend,ng-rs-81]}
      template:
        metadata:
          labels:
            app: myserver-myapp-frontend-label
        spec:
          containers:
          - name: myserver-myapp-frontend-label
            image: nginx:1.20.2
            ports:
            - containerPort: 80
            livenessProbe:
            #readinessProbe:
              tcpSocket:
                #port: 80
                port: 80
              initialDelaySeconds: 5
              periodSeconds: 3
              timeoutSeconds: 5
              successThreshold: 1
              failureThreshold: 3
    
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: myserver-myapp-frontend-service
      namespace: myserver
    spec:
      ports:
      - name: http
        port: 80
        targetPort: 80
        nodePort: 40012
        protocol: TCP
      type: NodePort
      selector:
        app: myserver-myapp-frontend-label
    
    

    3 exec-自定义命令

    [root@k8s-master1 probe]# cat 3-exec-Probe.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myserver-myapp-redis-deployment
      namespace: myserver
    spec:
      replicas: 1
      selector:
        matchLabels: #rs or deployment
          app: myserver-myapp-redis-label
        #matchExpressions:
        #  - {key: app, operator: In, values: [myserver-myapp-redis,ng-rs-81]}
      template:
        metadata:
          labels:
            app: myserver-myapp-redis-label
        spec:
          containers:
          - name: myserver-myapp-redis-container
            image: redis
            ports:
            - containerPort: 6379
            livenessProbe:
            #readinessProbe:
              exec:
                command:
                #- /apps/redis/bin/redis-cli
                - /usr/local/bin/redis-cli 
                - quit
              initialDelaySeconds: 5
              periodSeconds: 3
              timeoutSeconds: 5
              successThreshold: 1
              failureThreshold: 3
          
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: myserver-myapp-redis-service
      namespace: myserver
    spec:
      ports:
      - name: http
        port: 6379
        targetPort: 6379
        nodePort: 40016
        protocol: TCP
      type: NodePort
      selector:
        app: myserver-myapp-redis-label
    
    

    2.6 如何优雅的终止pod(prestop)

    poststart:
    pod被创建后立即执行检查,及不等的pod中的服务启动
    如果poststart执行失败pod不会被继续创建
    prestop:
    在pod被停止之前执行一些操作

    通俗的讲就是等待一定时间,才会执行prestop的操作,在等待的时间,可以把pod从注册中心移走,或者让pod下线,这样当执行prestop的之后,避免用户发送访问请求,造成页面打不开的故障。

    演示:

    [root@k8s-master1 probe]# cat 1-myserver-myapp1-postStart-preStop.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myserver-myapp1-lifecycle
      labels:
        app: myserver-myapp1-lifecycle
      namespace: myserver
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: myserver-myapp1-lifecycle-label
      template:
        metadata:
          labels:
            app: myserver-myapp1-lifecycle-label
        spec:
          terminationGracePeriodSeconds: 60  #终止等待期就是说等待60秒之后,才会执行prestop里的命令
          containers:
          - name: myserver-myapp1-lifecycle-label
            image: tomcat:7.0.94-alpine 
            lifecycle:
              postStart:
                exec:
                 #command: 把自己注册到注册在中心
                  command: ["/bin/sh", "-c", "echo 'Hello from the postStart handler' >> /usr/local/tomcat/webapps/ROOT/index.html"]
    
                #httpGet:
                #  #path: /monitor/monitor.html
                #  host: www.magedu.com
                #  port: 80
                #  scheme: HTTP
                #  path: index.html
              preStop:
                exec:
                 #command: 把自己从注册中心移除
                  command: ["/usr/local/tomcat/bin/catalina.sh","stop"]
            ports:
              - name: http
                containerPort: 8080
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: myserver-myapp1-lifecycle-service
      namespace: myserver
    spec:
      ports:
      - name: http
        port: 80
        targetPort: 8080
        nodePort: 30012
        protocol: TCP
      type: NodePort
      selector:
        app: myserver-myapp1-lifecycle-label
    
    
    

    大致流程:
    image

  • 相关阅读:
    采用springboot+flowable快速实现工作流
    07 Sublime Text3常用快捷键
    06 解决Sublime Text3输入法不跟随的问题
    04 Storage and Calculation C语言中的存储和计算
    05 sublime环境配置及编译运行后输出中文乱码的解决
    04 sublime text 3在线安装package control插件,之后安装主题插件和ConvertToUTF8 插件
    03 sublime text3下配置Java的编译运行环境
    02 sublime text3下配置Python的编译运行环境
    01 sublime text3下配置c/c++ 的编译运行环境
    03 Comments in C Programming C编程中的注释
  • 原文地址:https://www.cnblogs.com/huningfei/p/16270044.html
Copyright © 2020-2023  润新知