Closed4
K8s環境で任意のシェルスクリプトを実行するCronjob/Jobを作りたい
やりたいこと
K8s環境で任意のシェルスクリプトを実行するCronjob/Jobを作りたい。追加でkubectlコマンドを実行してその結果を反映させたい。
完成形
以下は毎時0時(UTC)に、Postman ECHOへcurlし、K8sのnamespaceを取得してechoするだけのcronjobです。
arbitrary-script.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: cronjob-serviceaccount
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cronjob-clusterrole
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "list"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cronjob-clusterrolebinding
subjects:
- kind: ServiceAccount
name: cronjob-serviceaccount
namespace: default
apiGroup: ""
roleRef:
kind: ClusterRole
name: cronjob-clusterrole
apiGroup: ""
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: run-arbitrary-script-cronjob
spec:
schedule: "0 0 * * *"
jobTemplate:
spec:
parallelism: 1
completions: 1
template:
metadata:
name: run-arbitrary-script-cronjob
spec:
serviceAccountName: cronjob-serviceaccount
volumes:
- name: scripts-volume
configMap:
name: run-arbitrary-script
containers:
- name: run-arbitrary-script
image: alpine
volumeMounts:
- mountPath: /scripts
name: scripts-volume
env:
- name: HOME
value: /tmp
- name: ENV
value: development
# - name: SECRET
# valueFrom:
# secretKeyRef:
# name: any-secret-whatever-you-want
# key: SECRET
command:
- /bin/sh
- -c
- |
cp /scripts/*.sh /tmp
chmod +x /tmp/*.sh
/tmp/bootstrap.sh
/tmp/run-arbitrary-script.sh $ENV
restartPolicy: Never
---
apiVersion: v1
kind: List
items:
- apiVersion: v1
kind: ConfigMap
metadata:
name: run-arbitrary-script
data:
bootstrap.sh: |
echo "=== Initialization"
apk add --no-cache --virtual=build-deps wget \
&& wget https://storage.googleapis.com/kubernetes-release/release/v1.23.0/bin/linux/amd64/kubectl \
&& mv kubectl /usr/local/bin/kubectl \
&& chmod +x /usr/local/bin/kubectl \
&& apk del build-deps
apk add --no-cache jq bash curl
run-arbitrary-script.sh: |
#!/bin/bash
ENV=$1
echo "=== run-arbitrary-script.sh"
curl -s "https://postman-echo.com/get?env=$ENV"|jq .args
namespaces=(`kubectl get namespace --no-headers -o custom-columns=":metadata.name"`)
for namespace in "${namespaces[@]}"
do
echo $namespace
done
$ kubectl create -f arbitrary-script.yaml
serviceaccount/cronjob-serviceaccount created
clusterrole.rbac.authorization.k8s.io/cronjob-clusterrole created
clusterrolebinding.rbac.authorization.k8s.io/cronjob-clusterrolebinding created
cronjob.batch/run-arbitrary-script-cronjob created
configmap/run-arbitrary-script created
# 手動でcronjobをトリガーする
$ kubectl create job --from=cronjob/run-arbitrary-script-cronjob run-arbitrary-script-cronjob-manually
job.batch/run-arbitrary-script-cronjob-manually created
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
run-arbitrary-script-cronjob-manually-94qb9 1/1 Running 0 8s
$ kubectl logs run-arbitrary-script-cronjob-manually-94qb9
...
OK: 11 MiB in 25 packages
=== run-arbitrary-script.sh
{
"env": "development"
}
default
kube-node-lease
kube-public
kube-system
補足
- kubectlコマンド等はalpine(何も入ってない最小のLinuxイメージ)に都度インストールして使えるようにしています。
- 任意のスクリプトをconfigmapに入れて保存することでK8s定義ファイルだけで自由にカスタマイズできるようにしています。
- Service Accountは意図的に全てのリソースに対してアクセス権限を持たせてます。実運用の際には適宜変更してご利用ください。
-
bootstrap.sh
部分をコンテナ化する際には以下のサイトが便利です。
参考にしたサイト
このスクラップは2022/10/18にクローズされました