2️⃣

Job手動実行後にConfigMapを自動削除するkubectlプラグインを作ってみた

2024/11/21に公開

はじめに

運用の中でCronJobを手動実行する対応がありました

当該バッチは手動実行が必要となる場面が見越されていて
手動実行時にのみ設定する環境変数がオプショナルなConfigMapから読み込まれます
そのConfigMapはほかの用途では使用していないためスケジュール実行の際は使用していません

実施手順としては以下の流れでした

  1. kubectl create configmap ${envFrom.configMapRef.name}
  2. kubectl create job xxx --from=cronjob/xxx
  3. kubectl delete job xxx

この対応の数日後、正規のスケジュールで実行されたCronJobが
想定と異なる動作をしてしまうというインシデントが発生

手動実行~インシデント発生の間に作成されたReplicaSetが
手動実行時に作成したConfigMapを参照してしまったようです

原因としては先に記載した手順にある通りConfigMapを削除していなかったことです

そこで今回はJobの手動実行後にConfigMapを自動削除するkubectlプラグインを作ってみました

kubectlプラグインとは

ざっくりと言えばパスが通っていて
ファイル名がkubectl-で始まる実行ファイルは
kubectlのサブコマンドとして実行できるという仕組みです

https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/

Goであれば

  • モジュール名を命名規則に沿ったものにする
    • e.g. github.com/miyamo2/kubectl-hello_world
  • 利用者がgo installでインストールする

だけで上記の要件を満たすことができます

また本家kubernetesやそのサブパッケージがGoで開発されていることから
今回はGoで開発しました

作ったもの

https://github.com/miyamo2/kubectl-create-transient-configmap

アプローチとしては単純に

  • create configmap
  • create job
  • wait job
  • delete job
  • delete configmap

を束ねるコマンドを作ってしまおうというもので
フラグなどのI/Fは極力create configmapcreate jobに寄せています

インストール

homebrew

brew install miyamo2/tap/kubectl-create-transient_configmap

go install

go install github.com/miyamo2/kubectl-create-transient_configmap@latest

使用例

マニフェスト

apiVersion: batch/v1
kind: CronJob
metadata:
  name: foo-batch
spec:
  timeZone: "Asia/Tokyo"
  schedule: "0 0 * * *"
  startingDeadlineSeconds: 100
  jobTemplate:
    spec:
      completions: 1
      parallelism: 1
      backoffLimit: 0
      template:
        spec:
          containers:
            - name: foo-batch
              image: foo-batch:latest
              imagePullPolicy: Never
              env:
                - name: NUM
                  valueFrom:
                    configMapKeyRef:
                      name: foo-configmap
                      key: num
                      optional: true
          restartPolicy: Never

実行コマンド

kubectl create transient_configmap foo-configmap \
--from-literal=num=1 \       # create configmapのfrom-literalと同様
--job-name=test \            # 作成するジョブの名前(必須)
--job-from=cronjob/foo-batch # create jobのfromと同様

ログ

creating configmap foo-configmap...
configmap/foo-configmap created
creating job test...
job.batch/test created
job "test" completed
deleting job test...
job.batch "test" deleted
deleting configmap foo-configmap...
configmap "foo-configmap" deleted
create transient_configmap completed

その他のフラグについてはこちらを参照してください

諸注意

ConfigMapを環境変数として使用するJobを想定して作っているため
ConfigMapをVolumesにマウントしているJobに関しては
バニラcreate configと同様に自動で同期されてしまいます

また、transient_configmapを使用している裏で

  • ReplicaSetが作成される
  • Podが再起動する

というシチュエーションに関しても現状考慮できていないので
何か良いアイデアがあればコメントかPRをいただけると嬉しいです

Discussion