半農半エンジニアの記録

関西在住エンジニア。個人で勉強・開発したこと、その他趣味のことを書いてます。農業してます。

【kubernetes】Pod間に依存関係を持たせるときの一工夫

Kubernetesにアプリをデプロイするにあたり、Podが1つということはあまりないと思う。

かつ複数のPod(AとB)を、Aが起動できてからBを起動させる、みたいに依存関係を持たせるのは一般的に考えられるユースケースだと思う。WEB + DBなんかは特に。

本記事はそんな話。

docker-compose

dockerをインストールすればdocker-composeもKubernetesもインストールできる。

まだKubernetesよりdocker-composeで複数コンテナ作ってみる人のほうが多いのではと思う。のでdocker-composeでのやり方と比較(というほどでもないが)しながら進めたい。

docker-composeはコンテナ間、KubernetesはPod間という違いはある。

docker-comopseではyamlファイルにdepends_onやlinksといったハッシュキーが用意されている。

version2からはこれらの違いは無くて、どちらもコンテナの依存関係を定義し、[エイリアス名]を使用してコンテナにアクセスすることができる。

依存関係を定義しておけば、依存元は依存先が立ち上げるのを待ってから、起動する。

Kubernetes

Kubernetesでは、docker-composeのように依存関係を明記する機能は備わっていない。

とはいえ必要な機能だからか、公式ページにやり方が記載されている。

PostStart

Container Lifecycle Hooksの1つに、PostStartというのがある。

公式ドキュメント

kubernetes.io

ざっくり訳す。

ここで定義した内容は、コンテナが作成された後に実行される。

ただし、コンテナのENTRYPOINTの前後どちらになるかは保証されない。

ふむ、今回の用途には不向きのようだ。

initContainers

containersとは別にinitContainersというのがある

公式ドキュメント

kubernetes.io

containersとの違い

こちらもざっくり訳す。

Init Containersでは、普通のContainerと同じfieldやfeatureをサポートしていて、resource limits, volumes, security settingなんかもある。でも、resource requestsやlimitsの扱いはちょっと違っていて、それはResourceのページ見てくれ。あとはreadiness probesはサポートしていない、だってPodがreadyになる前に完了するものだから。

複数のInit Containersがポッドにある場合、順番に走る。前のやつが成功するまで次のやつは走らない。すべてのInit Containersが完了したら、Podが初期化されて通常通りコンテナが実行される。

うん、これならいけそう。サンプルコードもそんな感じ。

nslookupは微妙?

公式のサンプルコードを抜粋する。

  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;

nslookupで名前解決できるまで走り続ける。つまり名前解決できた時点でInitContainerは終了して、containersで定義されているものが実行される。

これを使って、DBのポッドが起動した後に、そこに接続するアプリを含んだポッドを定義して試してみた。が、上手くいかない。

おそらく、DB起動コマンドが実行された瞬間にnslookupが成功していて、DBが正常に起動する前にDB接続をトライして失敗してるっぽい。

netcatでやってみる

少し修正し、netcatでポート指定。MySQLなので3306。

  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', 'until nc -z myservice 3306; do echo waiting for myservice; sleep 2; done;

これだと想定通り、DBがしっかり起動してからアプリのPodが起動し、DB接続も成功した。

まとめ

  • KubernetesでPod間に依存関係は作れる
  • 公式ページで紹介されている方法だと上手くいかないユースケースもある