PodのInitContainerとNode(GCE)のStartupScript
本記事
本記事では、たまたま趣味で使っているKubernetesで、PodやNodeを立ち上げた時に実行したい起動スクリプトのようなものがあります。
今回はどのようにそれを実現できるかを調べていた時にInitContainerとStartupScriptを知ったので、今回はその使い方を解説したいと思います。
内容
PodのInitContainer
InitContainerとは
以下の用語を定義します。
InitContainer
: InitContainer用のコンテナAppContainer
: アプリケーション用のコンテナ
このときにInitContainerはAppContainerよりも先に実行され、主にはAppContainerのための準備に使われたりします。
また、一つ以上のInitContainerを含むことができ、ランタイム中では一つずつ実行される。
注意点
以下の注意点があります。
- InitContainerはKuberenetesのJobのように
Completion
を目指してなるように実行されるため実装もそうしないといけない - AppContainerが起動されるには、すべてのInitContainerが
SUCCESS
しないといけない
追加方法
InitContainerを追加するにはspec.initContainers
を追加し以下のようにします。
1.6以上から
apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;'] - name: init-mydb image: busybox command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
もちろん普通のPodと同様にResource Request、Security、Volumnなどを定義することができますが、Resource Requestの使い方が少し違うので詳しくは参考文献をご覧ください。
NodeのStartupScript
StartupScript
GKEではデフォルトではStartupScriptは実現できません。
なのでDaemonSetを配置することで実現できます。
DaemonSet
以下のようなDaemonSetを渡します。
kind: DaemonSet apiVersion: extensions/v1beta1 metadata: name: startup-script labels: app: startup-script spec: template: metadata: labels: app: startup-script spec: hostPID: true containers: - name: startup-script image: gcr.io/google-containers/startup-script:v1 imagePullPolicy: Always securityContext: privileged: true env: - name: STARTUP_SCRIPT value: | #! /bin/bash set -o errexit set -o pipefail set -o nounset touch /tmp/foo echo done
ここではShell Scriptが渡されています。
NodePoolにStartupScriptを
Node PoolはKuberenetesクラスタが使用するNode群を定義されたものです。
以下のようにしてStartupScriptを渡します。
gcloud container node-pools create hoge-pool --metadata-from-file startup-script=scripts/install.sh
これによってdefault-pool
に起動スクリプトがついたものをNode Poolとして設定できました。
もちろんNode Poolは変更されるような対象ではないので既存のものには起動スクリプトを定義することはできないようです。
既存のPodのスケジュールをかえたいときはkubectl drain
を使うといいでしょう。以下の記事を参照ください。
Podに書き込まれるServiceの環境変数
PodがNodeにスケジュールされた時、有効なServiceについてそれぞれ環境変数をセットする。
たとえばService名がredis-master
だとすると
REDIS_MASTER_SERVICE_HOST=10.0.0.11 REDIS_MASTER_SERVICE_PORT=6379 REDIS_MASTER_PORT=tcp://10.0.0.11:6379 REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379 REDIS_MASTER_PORT_6379_TCP_PROTO=tcp REDIS_MASTER_PORT_6379_TCP_PORT=6379 REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11
の様にセットされます。
Podの情報をContainerに渡す方法
以下の記事で解説しているのでご覧ください。
TODO: Paste article