探针(probe)

探测机制

所谓的探测机制,就是运行命令

exec

在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。

例如,

echo $?

k8s pod无法创建容器_学习

tcpSocket

对容器的 IP 地址上的指定端口执行 TCP 检查。如果端口打开,则诊断被认为是成功的。 如果远程系统(容器)在打开连接后立即将其关闭,这算作是健康的。
例如,

telnet ip port

k8s pod无法创建容器_kubernetes_02

httpGet

对容器的 IP 地址上指定端口和路径执行 HTTP GET 请求。如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的。
例如,

curl -I http://ip:port

k8s pod无法创建容器_nginx_03

grpc(测试中)

使用 gRPC 执行一个远程过程调用。了解一下即可。

探针类型

看 deploy coredns 的yaml

kubectl get deploy coredns -n kube-system -oyaml

后面的为截取的内容

livenessProbe

存活探针,指示容器是否正在运行。如果存活状态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定何时重启。如果容器不提供存活探针, 则默认状态为Success。

livenessProbe:
          failureThreshold: 5
          httpGet:
            path: /health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 5
  • failureThreshold:失败次数
  • initialDelaySeconds:初始化时间
  • periodSeconds:检测间隔时间
  • successThreshold:成功次数
  • timeoutSeconds:超时时间

使用HttpGet的方式,发送数据包来探测。整个流程大致为,发送http数据包,若在5秒内收到200-400状态码,则成功,否则等待10s继续发送,直至失败5次,就认为失败了,容器没有存活。

readinessProbe

就绪探针,指示容器是否准备好为请求提供服务。如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始化之前的就绪态的状态值默认为 Failure。 如果容器不提供就绪探针,则默认状态为Success。

readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /ready
            port: 8181
            scheme: HTTP
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1

同样使用HttpGet的方式,发送数据包来探测

startupProbe

启动探针,指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被禁用,直到此探针成功为止。如果启动探测失败,kubelet 将杀死容器,而容器依其 重启策略进行重启。 如果容器没有提供启动探测,则默认状态为 Success。

Init Containers(初始化容器)

创建pod命令执行后,使用get po的时候看到的 Init,用于初始化,一般很小。
• 一直运行,直到完成。
• 每个都必须在下一个启动之前成功完成。

Ephemeral Containers(临时容器)

用于调试、故障排查
临时容器与其他容器的不同之处在于,它们缺少对资源或执行的保证,并且永远不会自动重启, 因此不适用于构建应用程序。 临时容器使用与常规容器相同的 ContainerSpec 节来描述,但许多字段是不兼容和不允许的。
• 临时容器没有端口配置,因此像 ports,livenessProbe,readinessProbe 这样的字段是不允许的。
• Pod 资源分配是不可变的,因此 resources 配置是不允许的。

模版

一个比较全的Pod yaml文件模板

apiVersion: v1 # 必选,API的版本号
kind: Pod       # 必选,类型 这里填Pod
metadata:       # 必选,元数据
  name: nginx   # 必选,符合RFC 1035规范的Pod名称
  namespace: default # 可选,Pod所在的命名空间,不指定默认为default,一般在kubectl中使用-n指定namespace 
  labels:       # 可选,标签选择器,一般用于过滤和区分Pod,可以写多个
    app: nginx
    role: frontend
  annotations:  # 可选,注释列表,可以写多个
    app: nginx
spec:   # 必选,用于定义容器的详细信息
  initContainers: # 可选,初始化容器,在容器启动之前执行的一些初始化操作
 - command:
    - sh
    - -c
    - echo "I am a InitContainer that init some configurations"
    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 # 检查成功为1次表示就绪
      failureThreshold: 2 # 检测失败2次表示未就绪
    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,总是拉取。Never不管是否存储都不拉取
  nodeSelector: # 可选,指定Node节点
        region: subnet7
  imagePullSecrets:     # 可选,拉取镜像使用的secret,可以配置多个
 - name: default-dockercfg-86258
  hostNetwork: false    # 可选,是否为主机模式,如是,会占用主机端口
  volumes:      # 共享存储卷列表
 - name: webroot # 名称,与上述对应
     emptyDir: {}    # 挂载目录
        hostPath:              # 挂载本机目录
          path: /etc/hosts

我下载了k8s源代码,可以查看一下PullPolicy

k8s pod无法创建容器_kubernetes_04

  • Always:kubelet pull最新镜像,pull失败,容器就启动失败。
  • Nerver:kubelet 不pull镜像,使用本地镜像,没有就失败。
  • IfNotPresent:kubelet在镜像没有时就pull,如果本地没有,pull也失败,容器启动失败。

博主喜欢使用第3个

创建

或许你看到前面的很长的yaml已经蒙了,那在这里我们就创建一个简单的仅包含一个nginx容器的Pod

apiVersion: v1
kind: Pod
metadata:
  name: nginx-test
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - name: http
      containerPort: 80