什么是Pod?
pod是kubernetes中最小的单元,由一组、一个或多个容器组成,每个pod中包含了一个pause容器。
pause容器是pod的父容器,主要负责僵尸进程的回收管理,通过pause容器可以使同一个pod中多个容器共享存储、网络、PID、IPC等,同一个Pod中多容器间访问仅通过localhost就可以通信。
为什么要引入Pod?
将有强依赖性的容器放在同一个Pod里,例如要求低延迟性,容器A与容器B之间文件上的联系等,引入Pod的概念是可以提高性能、便于管理。
从k8s角度说,docker是容器,但是容器却不只是docker,引入pod可以使容器间工作更协调。
定义一个Pod:pod.yaml
下面这个yaml文件可能复制有问题,你也可以使用下面命令生成一个yaml文件作为模板进行修改:
kubectl create deployment nginx --image=nginx -o yaml --dry-run=client >nginx.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: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
- apiserver:定义API的版本号
- kind:创建资源类型,如pod、deployment等
- metadata:元数据,如pod的一些基本信息
- spec:用于定义容器的详细信息
- 执行yaml文件创建Pod:
kubectl create -f pod.yaml
- 完成后查看Pod:
kubectl get pod
注意:生产中基本不会直接使用pod进行部署,但是yaml文件大同小异。需要熟悉yaml文件的格式和配置项。
Pod探针:
- StartupProbe:1.16版本后增加的探针方式,用于判断容器内应用程序是否已经启动,如果配置了StartupProbe,就会先禁止其他探测,直到成功,成功后将不在进程探测。
- LivenessProbe:用于探测容器是否运行,如果探测失败,kubelet会根据配置的重启策略进行相应的处理。若没有配置该探针,默认就是success。
- ReadinessProbe:一般用于探测容器内的程序是否健康,它的返回值如果为success,那么代表这个容器已经启动成功,并且程序已经是可以接受流量的状态。
Pod探针检测方式:
以上探针均可配置以下方式:
- ExecAction:在容器内执行一个命令,如果返回值为0,则认为容器健康(类似于执行一个命令后,执行echo $?返回值为0代表成功是一样的)
livenessProbe: exec: command: - cat - /tmp/health
- TCPSocketAction:通过TCP连接检查容器内的端口是否通的,如果是通的则认为容器健康(类似于telnet 127.0.0.1 3306,执行成功的话判断为容器健康)
livenessProbe: tcpSocket: port: 80
- HTTPGetAction:通过应用程序暴露的API地址来检查程序是否正常,如果状态码为200~400之间,则认为容器健康。(生产使用最多)
livenessProbe: httpGet: path: /status/health port: 80
探针检查的几个参数:
- initialDelaySeconds:初始化时间(比如程序启动慢,我要多少秒后才会检查)
- timeoutSeconds:超时时间(1-2秒)
- periodSeconds:检测间隔,多长时间检测一次(5秒)
- successThreshold:检测成功次数,比如检测成功几次代表就绪(1-2次)
- failureThreshold:检测失败次数,比如检测失败几次代表未就绪(2次)
- 重启策略:timeoutSecondsperiodSecondsfailureThreshold
- 我们可以看以下coredns的探针配置:
# 查看pod名称 [root@k8s-master01 ~]# kubectl get deployment -n kube-system coredns 1/1 1 1 5d18h # 在线编译coredns的yaml文件 [root@k8s-master01 ~]# kubectl edit deployment coredns -n kube-system livenessProbe: failureThreshold: 5 httpGet: path: /health port: 8080 scheme: HTTP initialDelaySeconds: 60 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 5 # 上面代表请求8080的/health接口,如果访问成功则保留容器不会被杀死 readinessProbe: failureThreshold: 3 httpGet: path: /ready port: 8181 scheme: HTTP periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 # 上面配置代表请求8181的/ready接口成功,说明容器可以正常开始工作了
Pod退出流程
Prestop:先去请求eureka接口,把自己的IP地址和端口号,进行下线,eureka从注册表中该应用的IP地址。然后容器进行sleep 90,kill ‘进程’;(注意90不是确定值,而是根据实际情况进行变化的)