目 录CONTENT

文章目录

Kubernetes基本概念

简中仙
2022-05-10 / 0 评论 / 0 点赞 / 71 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于2024-01-14,若内容或图片失效,请留言反馈。 本文如有错误或者侵权的地方,欢迎您批评指正!

这篇学习笔记是基于杜宽老师在51CTO上发布的视频课程制作的。在此,感谢杜宽老师的分享和教学。如有侵权,请及时联系我。版权归原作者所有,未经允许不得转载或使用。

一、k8s介绍

Kubernetes是谷歌以Borg为前身,基于谷歌15年生产环境经验的基础上开源的一个项目,Kubernetes致力于提供跨主机集群的自动部署、扩展、高可用以及运行应用程序容器的平台。

Kubernetes是谷歌开发的第三个容器管理系统,提供了资源调度、扩容缩容、服务发现、存储编排、自动部署和回滚,并且具有天生高可用、负载均衡、故障自动恢复等功能的“生态系统”,目前已成为云原生领域的标准。

二、基础组件概述

1、Master节点:整个集群的控制中枢

组件说明
Kube-APIServer是整个集群的控制中枢,提供集群中各个模块之间的数据交换,并将集群状态和信息存储到分布式键-值(key-value)存储系统Etcd集群中。同时它也是集群管理、资源配额、提供完备的集群安全机制的入口,为集群各类资源对象提供增删改查以及watch的REST API接口
Controller-Manager集群状态管理器,以保证Pod或其他资源达到期望值。当集群中某个Pod的副本数或其他资源因故障和错误导致无法正常运行,没有达到设定的值时,Controller Manager会尝试自动修复并使其达到期望状态
Scheduler是集群Pod的调度中心,主要是通过调度算法将Pod分配到最佳的Node节点,它通过APIServer监听所有Pod的状态,一旦发现新的未被调度到任何Node节点的Po(PodSpec.NodeName为空),就会根据一系列策略选择最佳节点进行调度
Etcd由CoreOS开发,用于可靠地存储集群的配置数据,是一种持久性、轻量型、分布式的键-值(key-value)数据存储组件,作为Kubernetes集群的持久化存储系统,一般生产环境中建议部署三个以上节点(奇数个)

注:集群规模达到一定程度时,Etcd要和master节点进行区分,避免部署在一台服务器,且Etcd必须使用SSD硬盘。

2、Node:工作节点(Worker、node节点、minion节点)

组件说明
Kubelet负责与Master通信协作,管理该节点上的Pod,对容器进行健康检查及监控,同时负责上报节点和节点上面Pod的状态
Kube-proxy负责各Pod之间的通信和负载均衡,将指定的流量分发到后端正确的机器上
Runtime负责容器的管理

查看Kube-proxy工作模式

[root@k8s-master01 ~]# curl 127.0.0.1:10249/proxyMode
ipvs

Ipvs:监听Master节点增加和删除service以及endpoint的消息,调用Netlink接口创建相应的IPVS规则。通过IPVS规则,将流量转发至相应的Pod上。

# ipvs中,dashboard的演示.
[root@k8s-master01 ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.17.0.1:31204 rr
  -> 172.169.244.196:8443         Masq    1      0          0
TCP  172.169.244.192:31204 rr
  -> 172.169.244.196:8443         Masq    1      0          0
TCP  10.4.7.107:31204 rr
  -> 172.169.244.196:8443         Masq    1      0          0
TCP  10.4.7.236:31204 rr
  -> 172.169.244.196:8443         Masq    1      1          0
TCP  10.96.0.1:443 rr
  -> 10.4.7.107:6443              Masq    1      0          0
  -> 10.4.7.108:6443              Masq    1      0          0
  -> 10.4.7.109:6443              Masq    1      1          0
TCP  10.96.0.10:53 rr
  -> 172.161.125.4:53             Masq    1      0          0
TCP  10.96.0.10:9153 rr
  -> 172.161.125.4:9153           Masq    1      0          0
TCP  10.98.15.94:443 rr
  -> 172.169.244.196:8443         Masq    1      0          0
TCP  10.102.175.175:443 rr
  -> 172.171.14.195:4443          Masq    1      3          0
TCP  10.108.133.81:8000 rr
  -> 172.169.92.67:8000           Masq    1      0          0
TCP  127.0.0.1:31204 rr
  -> 172.169.244.196:8443         Masq    1      0          0
UDP  10.96.0.10:53 rr
  -> 172.161.125.4:53             Masq    1      0          0
[root@k8s-master01 ~]# kubectl get svc -n kubernetes-dashboard
NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
dashboard-metrics-scraper   ClusterIP   10.108.133.81   <none>        8000/TCP        12h
kubernetes-dashboard        NodePort    10.98.15.94     <none>        443:31204/TCP   12h
[root@k8s-master01 ~]# kubectl get po -n kubernetes-dashboard -owide
NAME                                         READY   STATUS    RESTARTS   AGE   IP                NODE           NOMINATED NODE   READINESS GATES
dashboard-metrics-scraper-7645f69d8c-6ckjn   1/1     Running   2          12h   172.169.92.67     k8s-master02   <none>           <none>
kubernetes-dashboard-78cb679857-lrjkb        1/1     Running   2          12h   172.169.244.196   k8s-master01   <none>           <none>

Iptables:监听Master节点增加和删除service以及endpoint的消息,对于每一个Service,他都会场景一个iptables规则,将service的clusterIP代理到后端对应的Pod。

3、其他组件

组件说明
Calico符合CNI标准的一个网络插件,它负责给每个Pod分配一个不会重复的IP,并且把每个节点当做一各“路由器”,这样一个节点的Pod就可以通过IP地址访问到其他节点的Pod
CoreDNS用于Kubernetes集群内部Service的解析,可以让Pod把Service名称解析成Service的IP,然后通过Service的IP地址进行连接到对应的应用上

Calico: 符合 CNI标准的网络插件,给每个 Pod 生成一个唯一的IP地址,并且把每个节点当作一个路由器。

[root@k8s-master01 ~]# kubectl get po -n kube-system -owide
NAME                                       READY   STATUS    RESTARTS   AGE   IP               NODE           NOMINATED NODE   READINESS GATES
calico-kube-controllers-5f6d4b864b-rnw7z   1/1     Running   2          13h   10.4.7.109       k8s-master03   <none>           <none>
calico-node-78fgh                          1/1     Running   2          13h   10.4.7.111       k8s-node02     <none>           <none>
calico-node-bmm4m                          1/1     Running   2          13h   10.4.7.110       k8s-node01     <none>           <none>
calico-node-lz5pw                          1/1     Running   2          13h   10.4.7.109       k8s-master03   <none>           <none>
calico-node-ndhdr                          1/1     Running   2          13h   10.4.7.107       k8s-master01   <none>           <none>
calico-node-pqd7s                          1/1     Running   2          13h   10.4.7.108       k8s-master02   <none>           <none>
coredns-867d46bfc6-h9j7n                   1/1     Running   2          13h   172.161.125.4    k8s-node01     <none>           <none>
metrics-server-595f65d8d5-gzwxf            1/1     Running   2          13h   172.171.14.195   k8s-node02     <none>           <none>

CoreDNS: 用于kubernetes集群内部 service的解析,可以让 Pod 把service 名称解析成IP地址,然后通过 service的IP地址进行链接到对应的应用上。

[root@k8s-master01 ~]# kubectl get svc -n kube-system
NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
kube-dns         ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP,9153/TCP   13h
metrics-server   ClusterIP   10.102.175.175   <none>        443/TCP                  13h

三、Pod

Pod可简单地理解为是一组、一个或多个容器构成,每个Pod还包含一个Pause容器。

Pause容器是Pod的父容器,它主要负责僵尸进程的回收管理,同时通过Pause容器可以使同一个Pod里面的不同容器共享存储、网络、PID、IPC等,容器之间可以使用localhost:port相互访问,可以使用volume等实现数据共享。

根据Docker的构造,Pod可被建模为一组具有共享命令空间、卷、IP地址和Port端口的容器。

说明:Pod一般不直接操作,通过 Deployment、StatefulSet、DaemonSet控制。

1、为什么要引入pod

  • 强依赖的服务需要部署在一起
  • 多个服务需要协同工作时
  • 兼容其他CRI标准的运行时

2、定义一个 Pod

一份比较完整的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: 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:latest    # 必选,容器所用的镜像的地址
    imagePullPolicy: Always     # 可选,镜像拉取策略
    command: # 可选,容器启动执行的命令
    - 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
  #nodeSelector: # 可选,指定Node节点
  #      region: subnet7
  imagePullSecrets:     # 可选,拉取镜像使用的secret,可以配置多个
  - name: default-dockercfg-86258
  hostNetwork: false    # 可选,是否为主机模式,如是,会占用主机端口
  volumes:      # 共享存储卷列表
  - name: webroot # 名称,与上述对应
    emptyDir: {}    # 挂载目录
        #hostPath:              # 挂载本机目录
        #  path: /etc/hosts

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: 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
#

创建一个容器

# 创建一个pod
[root@k8s-master01 ~]# kubectl create -f pod.yaml 
pod/nginx created

# 查看刚刚创建的Pod
[root@k8s-master01 ~]# kubectl  get po
NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   4          17h
nginx     1/1     Running   0          5m24s

[root@k8s-master01 ~]# kubectl  get po --show-labels
NAME      READY   STATUS              RESTARTS   AGE   LABELS
busybox   1/1     Running             4          16h   <none>
nginx     0/1     Running   		  0          90s   app=nginx,role=frontend

# 删除一个po
[root@k8s-master01 ~]# kubectl delete po nginx
pod "nginx" deleted

# 创建到指定的命名空间
[root@k8s-master01 ~]# kubectl create -f pod.yaml  -n kube-public

# 创建命名空间
kubectl create ns ns_name

3、Pod状态及Pod故障排查命令

状态说明
Pending(挂起)Pod 已被 Kubernetes系统接收,但仍有一个或多个容器未被创建,可以通过kubectl describe查看处于Pending状态的原因
Running(运行中)Pod已经被绑定到一个节点上,并且所有的容器都已经被创建,而且至少有一个是运行状态,或者是正在启动或者重启,可以通过kubectllogs查看Pod的日志
Succeeded(成功)所有容器执行成功并终止,并且不会再次重启,可以通过kubectl logs查看Pod日志
Failed(失败)所有容器都已终止,并且至少有一个容器以失败的方式终止,也就是说这个容器要么以非零状态退出,要么被系统终止,可以通过logs和describe查看Pod日志和状态
Unknown(未知)通常是由于通信问题造成的无法获得Pod的状态
ImagePullBackOff ErrlmagePull镜像拉取失败,一般是由于镜像不存在、网络不通或者需要登录认证引起的,可以使用describe命令查看具体原因
CrashLoopBackOff容器启动失败,可以通过logs命令查看具体原因,一般为启动命令不正确,健康检查不通过等
OOMKilled容器内存溢出,一般是容器的内存Limit设置的过小,或者程序本身有内存溢出,可以通过logs查看程序启动日志
TerminatingPod正在被删除,可以通过describe查看状态
SysctlForbiddenPod 自定义了内核配置,但kubelet没有添加内核配置或配置的内核参数不支持,可以通过describe查看具体原因
Completed容器内部主进程退出,一般计划任务执行结束会显示该状态,此时可以通过logs查看容器日志
ContainerCreatingPod正在创建,一般为正在下载镜像,或者有配置不当的地方,可以通过describe查看具体原因

注意:Pod 的 Phase 字段只有 Pending、Running、Succeeded、Failed、Unknown,其余的为处于上述状态的原因,可以通过kubectl get po xxx-o yaml查看。

4、Pod镜像拉取策略

操作方式说明
Always总是拉取,当镜像tag为latest时,且imagePullPolicy未配置,默认为Always
Never不管是否存在都不会拉取
IfNotPresent镜像不存在时拉取镜像,如果tag为非latest,且imagePullPolicy未配置,默认为IfNotPresent

更改镜像拉取策略为IfNotPresent

apiVersion: v1 # 必选,API的版本号
kind: Pod       # 必选,类型Pod
metadata:       # 必选,元数据
  name: nginx   # 必选,符合RFC 1035规范的Pod名称
spec:   # 必选,用于定义容器的详细信息
  containers:   # 必选,容器列表
  - name: nginx # 必选,符合RFC 1035规范的容器名称
    image: nginx:1.15.2    # 必选,容器所用的镜像的地址
    imagePullPolicy: IfNotPresent     # 可选,镜像拉取策略, IfNotPresent: 如果宿主机有这个镜像,那就不需要拉取了. Always: 总是拉取, Never: 不管是否存储都不拉取
    ports:  # 可选,容器需要暴露的端口号列表
    - name: http    # 端口名称
      containerPort: 80     # 端口号    

5、Pod重启策略

操作方式说明
Always默认策略。容器失效时,自动重启该容器
OnFailure容器以不为0的状态码终止,自动重启该容器
Never无论何种状态,都不会重启

指定重启策略为never

apiVersion: v1 # 必选,API的版本号
kind: Pod       # 必选,类型Pod
metadata:       # 必选,元数据
  name: nginx   # 必选,符合RFC 1035规范的Pod名称
spec:   # 必选,用于定义容器的详细信息
  containers:   # 必选,容器列表
  - name: nginx # 必选,符合RFC 1035规范的容器名称
    image: nginx:1.15.2    # 必选,容器所用的镜像的地址
    imagePullPolicy: IfNotPresent     # 可选,镜像拉取策略, IfNotPresent: 如果宿主机有这个镜像,那就不需要拉取了. Always: 总是拉取, Never: 不管是否存储都不拉取
    command:
    - sleep
    - "10"
    ports:  # 可选,容器需要暴露的端口号列表
    - name: http    # 端口名称
      containerPort: 80     # 端口号   
  restartPolicy: never  

注意:重启策略是pod层面,配置在container层不生效

6、Pod探针

探针说明
StartupProbeKubernetes1.16新加的探测方式,用于判断容器内的应用程序是否已经启动。如果配置了startupProbe,就会先禁用其他探测,直到它成功为止。如果探测失败,Kubelet会杀死容器,之后根据重启策略进行处理,如果探测成功,或没有配置startupProbe,则状态为成功,之后就不再探测。
LivenessProbe用于探测容器是否在运行,如果探测失败,kubelet会“杀死”容器并根据重启策略进行相应的处理。如果未指定该探针,将默认为Success
ReadinessProbe一般用于探测容器内的程序是否健康,即判断容器是否为就绪(Ready)状态。如果是,则可以处理请求,反之Endpoints Controller将从所有的Service的Endpoints中删除此容器所在Pod的IP地址。如果未指定,将默认为Success

配置健康检查

apiVersion: v1 # 必选,API 的版本号 
kind: Pod  # 必选,类型 Pod 
metadata:  # 必选,元数据 
  name: nginx  # 必选,符合 RFC 1035 规范的 Pod 名称 
spec:  # 必选,用于定义 Pod 的详细信息 
  containers: # 必选,容器列表 
  - name: nginx  # 必选,符合 RFC 1035 规范的容器名称 
    image: nginx:1.15.12  # 必选,容器所用的镜像的地址 
    imagePullPolicy: IfNotPresent 
    command: # 可选,容器启动执行的命令 
    - sh 
    - -c 
    - sleep 10; nginx -g "daemon off;" 
    readinessProbe: # 可选,健康检查。注意三种检查方式同时只能使用一种。 
      httpGet:    # 接口检测方式 
        path: /index.html # 检查路径 
        port: 80 
        scheme: HTTP # HTTP or HTTPS 
        #httpHeaders: # 可选, 检查的请求头 
        #- name: end-user 
        #  value: Jason  
      initialDelaySeconds: 10       # 初始化时间, 健康检查延迟执行时间 
      timeoutSeconds: 2     # 超时时间 
      periodSeconds: 5      # 检测间隔 
      successThreshold: 1 # 检查成功为 2 次表示就绪 
      failureThreshold: 2 # 检测失败 1 次表示未就绪 
    livenessProbe:  # 可选,健康检查 
      tcpSocket:    # 端口检测方式 
        port: 80 
      initialDelaySeconds: 10       # 初始化时间 
      timeoutSeconds: 2     # 超时时间 
      periodSeconds: 5      # 检测间隔 
      successThreshold: 1 # 检查成功为 2 次表示就绪 
      failureThreshold: 2 # 检测失败 1 次表示未就绪
      ports:   # 可选,容器需要暴露的端口号列表 
  restartPolicy: always 

配置StartupProbe探针

apiVersion: v1 # 必选,API 的版本号 
kind: Pod  # 必选,类型 Pod 
metadata:  # 必选,元数据 
  name: nginx  # 必选,符合 RFC 1035 规范的 Pod 名称 
spec:  # 必选,用于定义 Pod 的详细信息 
  containers: # 必选,容器列表 
  - name: nginx  # 必选,符合 RFC 1035 规范的容器名称 
    image: nginx:1.15.12  # 必选,容器所用的镜像的地址 
    imagePullPolicy: IfNotPresent 
    command: # 可选,容器启动执行的命令 
    - sh 
    - -c 
    - sleep 30; nginx -g "daemon off;" 
    startupProbe: 
      tcpSocket:    # 端口检测方式 
         port: 80 
      initialDelaySeconds: 10       # 初始化时间 
      timeoutSeconds: 2     # 超时时间 
      periodSeconds: 5      # 检测间隔 
      successThreshold: 1 # 检查成功为 2 次表示就绪 
      failureThreshold: 5 # 检测失败 1 次表示未就绪 
    readinessProbe: # 可选,健康检查。注意三种检查方式同时只能使用一种。 
      httpGet:    # 接口检测方式 
        path: /index.html # 检查路径 
        port: 80 
        scheme: HTTP # HTTP or HTTPS 
        #httpHeaders: # 可选, 检查的请求头 
        #- name: end-user 
        #  value: Jason  
      initialDelaySeconds: 10       # 初始化时间, 健康检查延迟执行时间 
      timeoutSeconds: 2     # 超时时间 
      periodSeconds: 5      # 检测间隔 
      successThreshold: 1 # 检查成功为 2 次表示就绪 
      failureThreshold: 2 # 检测失败 1 次表示未就绪 
    livenessProbe:  # 可选,健康检查 
      exec:    # 端口检测方式 
          command: 
          - sh 
          - -c 
          - pgrep nginx 
      initialDelaySeconds: 10       # 初始化时间 
      timeoutSeconds: 2     # 超时时间 
      periodSeconds: 5      # 检测间隔 
      successThreshold: 1 # 检查成功为 2 次表示就绪 
      failureThreshold: 2 # 检测失败 1 次表示未就绪 
    ports:   # 可选,容器需要暴露的端口号列表 
    - containerPort: 80   # 端口号 
  restartPolicy: Never

说明:startupProbe 和 livenessProbe 最大的区别就是startupProbe在探测成功之后就不会继续探测了,而livenessProbe在pod的生命周期中一直在探测。这样设置之后,由于startupProbe探针的存在,程序有5X5s=25s的启动时间,一旦startupProbe探针探测成功之后,就会被readinessProbe接管,这样在运行中出问题readinessProbe就能在1X5=5s内发现。如果启动探测是3分钟内还没有探测成功,则接受Pod的重启策略进行重启。

注:在startupProbe执行完之后,其他2种探针的所有配置才全部启动,相当于容器刚启动的时候,所以其他2种探针如果配置了initialDelaySeconds,建议不要给太长

7、Pod探针的检测方式

检测方式说明
ExecAction在容器内执行一个指定的命令,如果命令返回值为0,则认为容器健康
TCPSocketAction通过TCP连接检查容器指定的端口,如果端口开放,则认为容器健康
HTTPGetAction对指定的URL进行Get请求,如果状态码在200~400之间,则认为容器健康

gRPC 探测

apiVersion: v1 
kind: Pod 
metadata: 
  name: etcd-with-grpc 
spec: 
  containers: 
  - name: etcd 
    image: registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.1-0 
    command: [ "/usr/local/bin/etcd", "--data-dir",  "/var/lib/etcd", "--listen-client-urls", "http://0.0.0.0:2379", "--advertise-client-urls", "http://127.0.0.1:2379", "--log-level", "debug"] 
    ports: 
    - containerPort: 2379 
    livenessProbe: 
      grpc: 
        port: 2379 
      initialDelaySeconds: 10

8、探针检查参数配置

参数说明
initialDelaySeconds: 60初始化时间
timeoutSeconds: 2超时时间
periodSeconds: 5检测间隔
successThreshold: 1检查成功为1次表示就绪
failureThreshold: 2检测失败2次表示未就绪

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

# 查看已有的配置
[root@k8s-master01 ~]# kubectl get deployment -n kube-system
NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
calico-kube-controllers   1/1     1            1           16h
coredns                   1/1     1            1           16h
metrics-server            1/1     1            1           16h
[root@k8s-master01 ~]# kubectl edit deploy coredns -n kube-system

9、Pod启动和退出流程

1、启动过程

1、kubectl提交创建pod指令到api server

2、pod处于pending(挂起)状态

3、确定pod所处节点位置之后,pod处于ContainerCreating状态

4、当pod镜像拉取完毕后,pod处于Running(运行中)状态

5、初始化操作完成后,pod启动完成

6、pod进行健康检查(探针)

7、在Endpoint中添加pod IP

2、退出流程

1、kubectl提交删除pod指令到api server

2、pod处于Dead状态,然后变为Terminating状态

3、配置生命周期(preStop)的情况下,命令将同时执行

4、在Endpoint中删除pod IP

Prestop:主要作用是将程序平滑退出,在springcloud程序中,先去请求注册中心接口,把自己的IP地址和端口号,进行下线,注册中心删除该应用的IP地址。然后容器进行sleep 90;kill pgrep java

apiVersion: v1 # 必选,API 的版本号 
kind: Pod  # 必选,类型 Pod 
metadata:  # 必选,元数据 
  name: nginx  # 必选,符合 RFC 1035 规范的 Pod 名称 
spec:  # 必选,用于定义 Pod 的详细信息 
  containers: # 必选,容器列表 
  - name: nginx  # 必选,符合 RFC 1035 规范的容器名称 
    image: nginx:1.15.12  # 必选,容器所用的镜像的地址 
    imagePullPolicy: IfNotPresent 
    lifecycle: 
      postStart: # 容器创建完成后执行的指令, 可以是 exec httpGet TCPSocket 
        exec: 
          command: 
          - sh 
          - -c 
          - 'mkdir /data/' 
      preStop: 
        exec: 
          command: 
          - sh 
          - -c 
          - sleep 10 
    ports:   # 可选,容器需要暴露的端口号列表 
    - containerPort: 80   # 端口号 
  restartPolicy: Never
0

评论区