筆者の学習時のデプロイ用コンテナイメージに対する疑問点
私のインフラ経験は、エンジニアとして初めての仕事だったスタートアップでの開発でした。
当時私はプログラミングスクールを出たてということもあり、当然インフラに対しての知識はほぼゼロでした。
AWSのEC2などを学び、その場でわかる知識だけでデプロイ作業をしてたこともあり、EC2インスタンスにApacheなどを直接インストールし、ソースコードはgithubから直接pullして変更を反映させるという、初心者まるだしの運用をしていました。
こういう経験をされてた方なら、本番環境でコンテナ運用と言われたときに、
「dockerエンジンが動いてるインスタンスで、Dockerコンテナが動くからコンテナ直接デプロイしちゃえばいいじゃん!ってのは分かった。でもこれソースコードの変更ってどう反映させるの?」
と、私と似た疑問を少しは抱いたのではないでしょうか?
k8sのDeploymentの文脈からの考察
DeploymentはReplicasetの世代管理をするのでした。そしてコンテナにまつわる世代の単位はImageのversionに他なりません。
つまり、kubernetesの無停止更新はImageのversion基準でまるっとupgrade(rollback)します。
よって、これはソースコードを含めたDockerImageを作成してDockerHubでソースコード込みのImageをVersion管理するんだなぁと言う理解になります。
DockerエンジンがファミコンでDockerImageがファミコンソフト
皆様はこの古代の機械をご存知でしょうか。
1980年代に日本を白熱させたファミリーコンピューターです。
当時、大抵のご家庭にこの機械がありました。
Dockerエンジンとはこういうどのご家庭にもあるハードウェアと想定してください。
そして、これがDockerImageです。
まぁ、ファミコンソフトなんですけど、要するにこのソフトはファミコンがあるご家庭ならどこでも起動できます。
このファミコンソフトの一つ一つがたとえば、pythonのコンテナ、phpのコンテナ、golangのコンテナ、node.jsのコンテナみたいな感じで、いろんな種類のソフトウェアだったとしても、Dockerエンジンというたった一つの規格を持っているごServerになら何処へでも提供できるわけ。
これが俗に言う可搬性(ポータビリティー)というやつです。
これで何が幸せなのか
一方で、インフラとソースコード分離されていた時代はどうだったでしょう。
例えばインフラにphp5.xが直接インストールされているとします。
そして、たとえばココではソースコードをlaravelとして、ソースコード側の依存ライブラリーを大幅アップデートしたとします。
そのアップデートの内容がphp7.x以上を要求する内容の場合、当然そのままデプロイしてしまうとphp5.x環境のインフラ上では動かなくなってしまいます。
これがDockerImage単位の管理になると、Developerがphpのversionもアップデートし、laravelのライブラリのアップデートも行い、local環境でその動作確認が取れたものをDockerImageとしてラッピングしてDockerHubへ出荷します。
そして、その動作確認が取れている製品は、Dockerエンジンというファミコンが動いているサーバー上でも当然動作します。
この場合サーバー側は何も設定を変える必要がない点がポイントです。
ただ、起動するコンテナを新しいVersionに切り替えるだけです。
これがDockerが次世代のOSだと言われる所以です。
まとめ
ファミコンが盛り上がっていた時代、ドラクエ1が出たと思ったらすぐにドラクエ2がでたりと、消費者はゲームに夢中でした。
この1とか2というのがDockerImageのVersionに該当します。
当時のファミコンビジネスの成功は、ファミコンという抽象化された規格を家庭に忍ばせることで、ソフト提供を爆速化できた点にあります。
DockerやKubernetesの文脈は、抽象化された規格をサーバーに提供することで、更新追加を爆速でUpdateできるということです。
だから、80年代に似た様なスキームで成功を収めていた日本がなぜkubernetesを作れなかったのかと、私は謎に思うわけです。