Kubernetes Pod 数据卷与健康检查
2020-03-30 by dongnan
开始之前
在前面的三篇文章中,至此我们已经准备好了K8S集群环境。
接下来我们将以在K8S集群运行一个真实的项目为目标,依次介绍项目所使用的K8S资源对象。
这个项目是一个典型的Web系统,使用 Java Spring Boot框架开发,需要使用 MySql、Redis数据库、NFS共享存储(多个Pod容器间共享文件)。
由于K8S环境部署在阿里云上,所以这里使用了阿里云提供的 RDS-Mysql 、RDS-Redis 数据库服务、NAS(NFS)
网络附加存储等中间件产品,对于K8S集群来说,我们需要将这些服务映射为K8S的资源对象。
项目使用的K8S的资源对象包括:
- PV&PVC,用于Pod数据卷(NFS)。
- Pod (volumeMounts、readinessProbe),挂载数据卷、健康检查。
- Secret,存储机密数据。
- Service,服务-外部域名(ExternalName)。
- NetworkPolicy,网络策略。
- LimitRange,限制资源。
- Ingress
环境
测试的k8s集群由一个Master管理节点、两个Worker计算节点组成,详细请参考这里。
目标
在上一篇文章 Kubernetes PV与PVC 介绍如何创建 PV与PVC,这篇文档目标有两个:
- 为Pod挂载数据卷(使用PVC存储资源)。
- 为Pod容器应用配置健康检查。
举个栗子
Yaml文档
这里Pod使用Deployment进行创建和管理,内容定义如下:
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: yii-prod
  name: yii-server
  labels:
    app: yii-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: yii-server
  template:
    metadata:
      labels:
        app: yii-server
    spec:
      imagePullSecrets: # docker registry repository
      - name: docker-repo
      containers:
      - name: yii-server
        image: hub.xyc.com/prod/yii-bulk:0.0.12
        ports:
        - containerPort: 8080
        readinessProbe:  # livenessProbe|readinessProbe
          tcpSocket:
            port: 8080
          initialDelaySeconds: 25
          periodSeconds: 10
          failureThreshold: 3
          successThreshold: 3
          timeoutSeconds: 5
        env: # environment
        - name: logtail
          value: 'true'
        - name: JAVA_OPTS
          value: '-Xmx2000m'
        volumeMounts:         
        - name: www-data  # pvc
          mountPath: /var/www/files
          subPath: www-data
      # volumes 
      volumes:
      - name: www-data
        persistentVolumeClaim:
          claimName: yii-server-pvc
      #- name: log-data
      #  emptyDir: {}
      # disable environment discover
      enableServiceLinks: false
注意, imagePullSecrets 选项,它是用来拉取Docker私有仓库镜像的,
这里涉及 Kubernetes Secret 知识点,我们将在下一篇文章讲解。
Pod数据卷
在 Pod 定义一个Volume数据卷:
  volumes:
  - name: `www-data`
    persistentVolumeClaim:
      claimName: yii-server-pvc
- 数据卷名称为www-data
- 数据卷类型为persistentVolumeClaim
- 对应PVC名称为yii-server-pvc
在 Pod 中使用数据卷:
    volumeMounts:         
    - name: `www-data`
      mountPath: /var/www/files
      subPath: www-data
- name:数据卷名称,这里为- www-data。
- mountPath:数据卷被挂载到容器的路径,这里为- /var/www/files。
- subPath:(可选项)容器在挂载数据卷时指向数据卷内部的一个子路径,而不是直接指向数据卷的根路径,也就是说会创建一个- www-data子目录。
Pod健康检查
Pod 通过两类探针来检查容器的健康状态,分别是 LivenessProbe(存活性探测)和 ReadinessProbe(就绪型探测):
这里采用的方案是监控Pod应用的服务端口(8080),也就是 readinessProbe:
readinessProbe:  # livenessProbe|readinessProbe
  tcpSocket:
    port: 8080
  initialDelaySeconds: 25
  periodSeconds: 10
  failureThreshold: 3
  successThreshold: 3
  timeoutSeconds: 5
主要参数:
- tcpSocket:通过容器的- IP地址和- 端口号进行- TCP检查,如果能够建立- TCP连接,则表明容器健康。
- initialDelaySeconds:存活性探测延迟时长,即容器启动多久后再开始第- 1次探测操作,默认为- 0秒,设置- 10秒是因为- Spring Boot框架需要初始化时间。
- periodSeconds:存活性探测的频率,默认为- 10秒(最小值为- 1s)。需要注意的是:过高的频率会对- pod对象带来额外的开销,而过低的频率又会使错误的反应不及时。
- failureThreshold:处于成功状态时,探测操作连续多少次的失败才被视为是检测不通过,默认值为- 3秒(最小值为- 1s)。
- successThreshold:处于失败状态时,探测操作连续多少次的成功才被认为是通过检测,默认值为- 1秒。
- timeoutSeconds:存活性探测的超时时长,默认为- 1秒(最小值为- 1s)。
创建Pod
kubectl apply -f yii-server.yaml
验证Pod
创建的 Deployment,名称为 yii-server
kubectl -n yyi-prod get deployment yyi-server 
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
yyi-server     1/1     1            1           157d
创建的 Pod 名称为 yii-server-78dxxx94d-gxxxr
kubectl -n yyi-prod get pod
NAME                            READY   STATUS    RESTARTS   AGE
yii-server-78dxxx94d-gxxxr      1/1     Running   0          157d
这与上篇文章中 PVC Mounted By 为同一个Pod:
kubectl -n yunyi-prod describe pod yii-server-78dxxx94d-gxxxr | awk 'NR >=47 && NR <= 51'
Volumes:
  www-data:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  yii-server-pvc     # 注意这里
    ReadOnly:   false
小结
- 使用 readinessProbe对Pod容器的IP+8080端口号进行TCP检查,首次检查延迟设置25秒,后续每10秒检查一次,超时时间为5秒;
- 超过3次检查失败则认为此Pod不可用,从Service服务列表中移除,反之失败状态下超过3次检查成功,则认为此Pod可用加入Service服务列表。
- 对于 Kubernetes Volumes需要注意的是Pod与PVC需要在同一个命名空间里。