定期的にPodを再作成する方法

背景

簡単に定期的にPodを再作成する方法を紹介します。

なんで定期的にPodを再作成したくなるかというと、例えば以下のような理由が思いつきます。

  • メモリリークしていてずっと稼働させるのはまずい
  • DBを負荷に応じてオートスケールさせていて、スケールアウトした新しいDBをアプリケーションに認識させたい

自分は2番目の理由でした。

どうやってやるか

kubectl rollout restart deployment名というコマンドがあり、これを使うと指定したdeploymentのpodを再作成してくれます。 kubernetes.io

このkubectl rollout restartコマンドをCronJobを使って定期的に実行してあげればよさそうです。 そのためにはkubectlコマンドを実行できるimageが必要になります。 自分で作成してもいいのですが、bitnamiがちょうどkubectlというimageを提供してくれているのでこれを使います。
https://hub.docker.com/r/bitnami/kubectl/

またPod内からkubectlを使ってKubernetes APIを叩くにはRBACの設定が必要になります。

マニフェストファイル例

service-account.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-rollout-restart

cronjob.yaml

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: my-rollout-restart-cronjob
spec:
  schedule: "30 12 * * *"
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: my-rollout-restart
          containers:
            - name: my-rollout-restart-job
              image: bitnami/kubectl:1.20
              command: ['kubectl', 'rollout' ,'restart', 'deployment/my-api-deployment']
          restartPolicy: OnFailure

role.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: my-rollout-restart-role
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "patch"]

rolebinding.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: my-rollout-restart-role-binding
subjects:
  - kind: ServiceAccount
    name: my-rollout-restart
roleRef:
  kind: Role
  name: my-rollout-restart-role
  apiGroup: rbac.authorization.k8s.io