一、使用CronJob定期重启K8s服务

3.3.1 环境准备

1、创建一个 MySQL 的 PVC

# 定义PVC
[root@k8s-master01 ~]# vim mysql-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-data
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  storageClassName: nfs-csi

# 创建PVC
[root@k8s-master01 ~]# kaf mysql-pvc.yaml

# 验证
[root@k8s-master01 ~]# kg pvc
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
mysql-data   Bound    pvc-1c159b41-7afd-467f-a8b9-ecfdf9089ef5   10Gi       RWX            nfs-csi        <unset>                 2s

2、创建一个 MySQL 的 Deployment

[root@k8s-master01 ~]# vim deployment-mysql.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: mysql
  name: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  strategy:
    type: Recreate  # 单实例策略,适合有状态应用
  template:
    metadata:
      labels:
        app: mysql   # 必须与selector.matchLabels一致
    spec:
      containers:
      - name: mysql
        image: registry.cn-hangzhou.aliyuncs.com/abroad_images/mysql:8.0.20
        ports:
        - containerPort: 3306  # 暴露MySQL默认端口
          protocol: TCP
        env:
        - name: MYSQL_ROOT_PASSWORD  # 建议生产环境改用Secret
          value: "123456"            # 示例密码,实际需加密
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql  # MySQL数据持久化目录
        livenessProbe:               # 存活探针
          tcpSocket:
            port: 3306
          initialDelaySeconds: 30    # 容器启动30秒后开始探测
          timeoutSeconds: 3          # 探测超时时间
          periodSeconds: 30          # 每30秒探测一次
          successThreshold: 1
          failureThreshold: 2        # 连续失败2次标记为不健康
        readinessProbe:              # 就绪探针(配置同存活探针)
          tcpSocket:
            port: 3306
          initialDelaySeconds: 30
          timeoutSeconds: 3
          periodSeconds: 30
          successThreshold: 1
          failureThreshold: 2
      volumes:                       # 卷定义(与containers同级)
      - name: data
        persistentVolumeClaim:
          claimName: mysql-data      # 关联的PVC名称
      dnsPolicy: ClusterFirst        # DNS解析策略(默认值)

3、创建MySQL,并查看启动状态

[root@k8s-master01 ~]# kaf deployment-mysql.yaml 

# 验证
[root@k8s-master01 ~]# kgp
NAME                    READY   STATUS    RESTARTS   AGE
mysql-676759b6c-g9jj7   1/1     Running   0          53s

3.3.2 定期重启K8s服务

有时候需要定期重启 K8s 中的服务,也可以使用 CronJob 实现。

如果一个时间点需要重启多个服务,则把命令写入多行即可

...
...
        spec:
          containers:
          - command:
            - /bin/bash
            - -c
            - kubectl rollout restart deployment mysql -n default
            - kubectl rollout restart deployment a -n default
            - kubectl rollout restart deployment b -n default
            - kubectl rollout restart deployment xxx -n default
...
...

如果不同时间点需要重启多个服务,则拆分多个cronjob即可

# 每周六凌晨两点重启下default命名空间下的mysql应用
kubectl create cronjob restart \
  --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/kubectl:latest \
  --schedule="01 18 * * 5" \
  --dry-run=client -o yaml \
  -- /bin/bash -c "kubectl rollout restart deployment mysql -n default" \
  > restart-cronjob.yaml

# 每周日凌晨两点重启下default命名空间下的a应用和b应用
kubectl create cronjob restart \
  --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/kubectl:latest \
  --schedule="01 18 * * 6" \
  --dry-run=client -o yaml \
  -- /bin/bash -c "kubectl rollout restart deployment a -n default" 
  -- /bin/bash -c "kubectl rollout restart deployment b -n default" 
\
  > restart-cronjob.yaml  

# 每周五凌晨两点重启下default命名空间下的b应用
kubectl create cronjob restart \
  --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/kubectl:latest \
  --schedule="01 18 * * 4" \
  --dry-run=client -o yaml \
  -- /bin/bash -c "kubectl rollout restart deployment b -n default" \
  > restart-cronjob.yaml 

下面进行示例演示:每周六凌晨两点重启default命名空间的mysql应用

1、创建一个命名空间

k create ns cronjob

2、创建重启 K8s 服务的权限

# 创建ClusterRole
k create clusterrole deployment-restart --verb=get,update,patch --resource=deployments.apps

# 创建ClusterRolebinding
kubectl create clusterrolebinding deployment-restart-binding \
  --clusterrole=deployment-restart \
  --serviceaccount=cronjob:default

3、创建cronjob

输出cronjob模板文件,每周六凌晨两点重启下default命名空间下的mysql应用

kubectl create cronjob restart \
  --image=registry.cn-hangzhou.aliyuncs.com/abroad_images/kubectl:latest \
  --schedule="01 18 * * 5" \
  --dry-run=client -o yaml \
  -- /bin/bash -c "kubectl rollout restart deployment mysql -n default" \
  > restart-cronjob.yaml

重新定义cronjob文件,每周六凌晨两点重启下default命名空间下的mysql应用

[root@k8s-master01 ~]# vim restart-cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: restart
  namespace: cronjob
spec:
  concurrencyPolicy: Allow
  suspend: false
  schedule: 01 18 * * 5
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 3
  jobTemplate:
    metadata:
      name: restart
    spec:
      template:
        metadata:
        spec:
          containers:
          - command:
            - /bin/bash
            - -c
            - kubectl rollout restart deployment mysql -n default
            image: registry.cn-hangzhou.aliyuncs.com/abroad_images/kubectl:latest
            name: restart
            resources: {}
          restartPolicy: Never

创建crontab

[root@k8s-master01 ~]# kaf  restart-cronjob.yaml

# 验证
[root@k8s-master01 ~]# kg cj -n cronjob
NAME      SCHEDULE      TIMEZONE   SUSPEND   ACTIVE   LAST SCHEDULE   AGE
restart   01 18 * * *   <none>     False     0        <none>          2s

4、手动触发crontab

# 触发前查看deploy的age时间,观察到为10分钟
[root@k8s-master01 ~]# kg deploy 
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
mysql   1/1     1            1           10m

# 手动触发
[root@k8s-master01 ~]# k create  job restart-deploy-test --from=cronjob.batch/restart -n cronjob

5、验证

# 查看job
[root@k8s-master01 ~]# kg job -n cronjob
[root@k8s-master01 ~]# kg job -n cronjob
NAME                  STATUS     COMPLETIONS   DURATION   AGE
restart-deploy-test   Complete   1/1           31s        3m24s

# 查看pod
[root@k8s-master01 ~]# kgp -n cronjob
NAME                        READY   STATUS      RESTARTS   AGE
restart-deploy-test-c9t96   0/1     Completed   0          85s

# 查看执行记录
[root@k8s-master01 ~]# k logs -f restart-deploy-test-c9t96 -n cronjob
deployment.apps/mysql restarted

# 查看default命名空间的pod,已重启
[root@k8s-master01 ~]# kgp
NAME                     READY   STATUS    RESTARTS   AGE
mysql-6ccd44dffc-vvbk4   1/1     Running   0          84s

6、环境复原

k delete -f  restart-cronjob.yaml -f deployment-mysql.yaml  -f mysql-pvc.yaml