Kubernetes クラスタ内に一時的な Pod をデプロイして kubectl コマンドを実行したい
Kubernetes クラスタ内に一時的な Pod をデプロイして、その Pod から kubectl
コマンドを実行し、Kubernetes クラスタを操作したいと思った。
一時的な Pod を作るだけなら、$ kubectl run
に --rm
オプションと --restart=Never
を使えば良い。その場で Docker イメージをダウンロードし、コンテナ・Pod として展開、シェルに接続できる。
# 一時的な Pod を作る
$ kubectl run temp-node --image=node:15 --namespace=default --rm -it --restart=Never --command -- bash
# 生成された Pod 内で kubectl コマンドをインストールする
$$ curl -sL "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" -o /usr/local/bin/kubectl && chmod +x /usr/local/bin/kubectl
色々調べると、kubectl
コマンドを使わずとも、次のようにトークンを利用すれば、Pod 一覧を取得したりできるらしいのだが、権限が足りずできなかった。コレはデフォルトの挙動として真っ当なモノらしい。
# 権限付与が要る
$$ curl -ik -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc.cluster.local/api/v1/namespaces/default/pods
当然、ホストマシンから KubeConfig ファイルをコピーしたりすれば、動かすことはできるが、なんかダサい。
# Pod 内でディレクトリだけ作っておく
$$ mkdir -p /root/.kube/
# ホストマシン側から Pod に対して KubeConfig ファイルを転送する
$ kubectl cp ~/.kube/my-config temp-node:/root/.kube/config
というワケで、こんなことをしなくてもいいように、ServiceAccount と ClusterRoleBinding という、権限管理用のリソースを作ってやる。
service-account-kubectl-in-cluster.yaml
# Service Account を作る
apiVersion: v1
kind: ServiceAccount
metadata:
name: kubectl-in-cluster
namespace: default
cluster-role-binding-kubectl-in-cluster.yaml
# 作成した Service Account に cluster-admin 権限をバインディングする
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubectl-in-cluster-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: kubectl-in-cluster
namespace: default
このような YAML ファイルを作って、Kubernetes クラスタに投入する。
$ kubectl apply -f cluster-role-binding-kubectl-in-cluster.yaml
$ kubectl apply -f service-account-kubectl-in-cluster.yaml
# デプロイできたか確認する
$ kubectl get serviceaccount --namespace default
$ kubectl clusterrolebinding
一時的な Pod を作る際、投入した Service Account を使うよう、--serviceaccount
オプションを指定する。
$ kubectl run temp-node --image=node:15 --namespace=default --serviceaccount=kubectl-in-cluster --rm -it --restart=Never --command -- bash
# kubectl コマンドはとりあえず入れるとして…
$$ curl -sL "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" -o /usr/local/bin/kubectl && chmod +x /usr/local/bin/kubectl
# 次のようなコマンドが動くようになった
$$ kubectl get pod
できたできた。
ちなみに、コマンドで実現していた一時 Pod の生成を YAML ファイルに起こすと、こんな感じ。
apiVersion: v1
kind: Pod
metadata:
labels:
app: kubectl
name: temp-node
namespace: default
spec:
serviceAccountName: kubectl-in-cluster
restartPolicy: Never
containers:
- name: temp-node
image: node:15
lifecycle:
postStart:
exec:
# ココで kubectl を用意しておく
command: ['sh', '-c', 'curl -sL "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" -o /usr/local/bin/kubectl && chmod +x /usr/local/bin/kubectl']
# ['bash'] でもとりあえず死なない。tty: true や stdin: true を付けても kubectl apply -f 直後にシェルにアタッチはされないみたい
command: ['tail', '-f', '/dev/null']
コレを $ kubectl apply -f
で投入して、$ kubectl attach 【Pod 名】
でアタッチすれば良さそう。
- Kubernetesクラスター内のPodからkubectlを実行する - Qiita
- docker - How to run kubectl commands inside a container? - Stack Overflow
- ServiceAccount を作成して Pod から kubectl を使って Pod の情報を取得する - Qiita
- ServiceAccount を作成し、Pod から
kubectl get pods
をやってみた時のメモ - Qiita - KubernetesにおけるPodの初期化処理 - Qiita
- kubernetesでPod起動時にコマンドを実行する - Qiita