K8s Pod原理和运用

Pod概念

什么是Pod?

Pod可简单地理解为是一组、一个或多个容器,具有共享存储/网络及如何运行容器的规范。Pad包含一个或多个相对紧密耦合的应用程序容器,处于同一个Pod中的容器共享同样的存储空间(Volume,卷或存储卷)、IP地址和Port端口,容器之间使用localhost:port相互访问。根据Docker的构造,Pod可被建模为一组具有共享命令空间、卷、IP地址和Port端口的Docker容器。 Pod包含的容器最好是一个容器只运行一个进程。每个Pod包含一个pause容器,pause容器是Pod的父容器,它主要负责僵尸进程的回收管理。 Kubernetes为每个Pod都分配一个唯一的IP地址,这样就可以保证应用程序使用同一端口,避免了发生冲突的问题

Pod字段解析

apiVersion: v1 # 必选,API的版本号
kind: Pod    # 必选,类型Pod
metadata:    # 必选,元数据
  name: nginx    # 必选,符合RFC 1035规范的Pod名称
  namespace: web-testing # 可选,不指定默认为default,Pod所在的命名空间
  labels:    # 可选,标签选择器,一般用于Selector
    - app: nginx
  annotations:    # 可选,注释列表
    - app: nginx
spec:    # 必选,用于定义容器的详细信息
  containers:    # 必选,容器列表
  - name: nginx    # 必选,符合RFC 1035规范的容器名称
    image: nginx: v1    # 必选,容器所用的镜像的地址
    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: 1024MiB
          requests:    # 启动所需的资源
            cpu: 100m
            memory: 512MiB
        readinessProbe:    # 可选,容器状态检查
        httpGet:    # 检测方式
            path: /    # 检查路径
            port: 80    # 监控端口
          timeoutSeconds: 2    # 超时时间 
          initialDelaySeconds: 60    # 初始化时间
        livenessProbe:    # 可选,监控状态检查
          exec:    # 检测方式
            command: 
            - cat
            - /health
          httpGet:    # 检测方式
            path: /_health
            port: 8080
            httpHeaders:
            - name: end-user
              value: jason
          tcpSocket:    # 检测方式
            port: 80
          initialDelaySeconds: 60    # 初始化时间
          timeoutSeconds: 2    # 超时时间
          periodSeconds: 5    # 检测间隔
          successThreshold: 2 # 检查成功为2次表示就绪
          failureThreshold: 1 # 检测失败1次表示未就绪
        securityContext:    # 可选,限制容器不可信的行为
          provoleged: false
      restartPolicy: Always    # 可选,默认为Always
      nodeSelector:    # 可选,指定Node节点
        region: subnet7
      imagePullSecrets:    # 可选,拉取镜像使用的secret
      - name: default-dockercfg-86258
      hostNetwork: false    # 可选,是否为主机模式,如是,会占用主机端口
      volumes:    # 共享存储卷列表
      - name: webroot # 名称,与上述对应
        emptyDir: {}    # 共享卷类型,空
        hostPath:        # 共享卷类型,本机目录
          path: /etc/hosts
        secret:    # 共享卷类型,secret模式,一般用于密码
          secretName: default-token-tf2jp # 名称
          defaultMode: 420 # 权限
          configMap:    # 一般用于配置文件
          name: nginx-conf
          defaultMode: 420

 


1.1 创建一个 Pod

定义一个 Pod
# vim nginx.yaml
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: nginx:1.15.12 # 必选,容器所用的镜像的地址
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
创建 Pod:
# kubectl create -f nginx.yaml
pod/nginx created
查看 Pod 状态:
# kubectl get po nginx
NAME READY STATUS RESTARTS AGE
nginx 0/1 ContainerCreating 0 20s
使用 kubectl run 创建一个 Pod:
# kubectl run nginx-run --image=nginx:1.15.12

 

 

1.2 更改 Pod 的启动命令和参数

# vim nginx.yaml
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: nginx:1.15.12 # 必选,容器所用的镜像的地址
command: # 可选,容器启动执行的命令
- sleep
- "10"
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号

 

 

1.3 Pod 状态及 Pod 故障排查命令

状态

说明

Pending(挂起) 

Pod 已被 Kubernetes 系统接收,但仍有一个或多个容器未被创建,可以通过

kubectl describe 查看处于 Pending 状态的原因 

Running(运行中) 

Pod 已经被绑定到一个节点上,并且所有的容器都已经被创建,而且至少有一个

 

是运行状态,或者是正在启动或者重启,可以通过 kubectl logs 查看 Pod 的日志 

Succeeded(成功) 

所有容器执行成功并终止,并且不会再次重启,可以通过 kubectl logs 查看 Pod 日志 

Failed(失败) 

所有容器都已终止,并且至少有一个容器以失败的方式终止,也就是说这个容器要么以非零状态退出,要么被系统终止,可以通过 logs describe 查看 Pod 日志和状态 

Unknown(未知) 

通常是由于通信问题造成的无法获得 Pod 的状态 

ImagePullBackOff

ErrImagePull

镜像拉取失败,一般是由于镜像不存在、网络不通或者需要登录认证引起的,可以使用 describe 命令查看具体原因 

CrashLoopBackOff

容器启动失败,可以通过 logs 命令查看具体原因,一般为启动命令不正确,健康检查不通过等 

OOMKilled

容器内存溢出,一般是容器的内存 Limit 设置的过小,或者程序本身有内存溢出,可以通过 logs 查看程序启动日志 

Terminating

Pod 正在被删除,可以通过 describe 查看状态 

SysctlForbidden      

Pod 自定义了内核配置,但 kubelet 没有添加内核配置或配置的内核参数不支持,可以通过 describe 查看具体原因 

Completed

容器内部主进程退出,一般计划任务执行结束会显示该状态,此时可以通过 logs 查看容器日志 

ContainerCreating

Pod 正在创建,一般为正在下载镜像,或者有配置不当的地方,可以通过 describe 查看具体原因 


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




 

1.4 Pod 镜像拉取策略 

通过 spec.containers[].imagePullPolicy 参数可以指定镜像的拉取策略,目前支持的策略如下:
操作方式 说明
Always 
总是拉取,当镜像 tag 为 latest 时,且 imagePullPolicy 未配置,默认为 Always
Never
不管是否存在都不会拉取
IfNotPresent 
镜像不存在时拉取镜像,如果 tag 为非 latest,且 imagePullPolicy 未配置,默认为 IfNotPresent 
更改镜像拉取策略为 IfNotPresent: 
# vim nginx.yaml
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 # 可选,镜像拉取策略
 ports: # 可选,容器需要暴露的端口号列表
 - containerPort: 80 # 端口号

 

 

 

1.5 Pod 重启策略

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

 

 指定重启策略为 Never:

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: # 可选,容器启动执行的命令
 - sleep
 - "10"
 ports: # 可选,容器需要暴露的端口号列表
 - containerPort: 80 # 端口号
 restartPolicy: Never




1.6 Pod 的三种探针

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


 
 

1.7 Pod探针的实现方式

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

1.8 livenessProbe和readinessProbe

创建一个没有探针的Pod:
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;"
 ports: # 可选,容器需要暴露的端口号列表
 - containerPort: 80 # 端口号
 restartPolicy: Never
配置健康检查: 
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: # 可选,容器需要暴露的端口号列表
 - containerPort: 80 # 端口号
 restartPolicy: Never

 

 

1.9 配置 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

  

 

1.10 preStop 和 postStart 

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

 

 

1.11 gRPC 探测(1.24 默认开启)

apiVersion: v1
kind: Pod
metadata:
 name: etcd-with-grpc
spec:
 containers:
 - name: etcd
 image: registry.cnhangzhou.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

 



posted @ 2022-09-27 15:38  背锅的Mike  阅读(233)  评论(0编辑  收藏  举报