Docker Kubernetesとその他 - 実用的

展開の旅を始める前に、この記事をチェックリストとして考えて欲しいです(内容は変わるかもしれないけれど、プロセスやステップはほとんど同じであることが多い)。

これから書くステップは、将来の自分や周りの開発者やテック系の人たちが日々取り組むこの技術側面で役立つようにメモっておくためのものです。

注記:ローカルでk8を動かす場合、minikubeやdocker desktopなどを試すことができます。ただし、ここでは本番シナリオが描かれています。つまり、クラウド上でk8が動いています。クラウドプロバイダーによって、それぞれのk8を使ってください。Azureの場合はAKS、AWSはEKS、GCPはGKEを使います。

まずは、クラウドスタックで物事がどう配置されているかを、高レベルから見てみましょう。

(画像がここに表示される)

上の図の簡単な説明です。

  • Kubernetesクラスタ: Kubernetes環境全体を表します。
  • ノード: 仕事を実行する物理的または仮想マシン。この図では、2つのノード(ノード1とノード2)があります。
  • ポッド: Kubernetesで作成し管理できる最小の展開ユニット。各ポッドは1つ以上のコンテナを含んでいます。
  • Dockerコンテナ: アプリケーションを実行するコンテナ。ポッドによって管理されています。

では、Reactアプリケーションをデプロイしてみましょう(GitHubのオープンソースを手に入れたり、サンプルプロジェクトを使ったりしても良いです)。Node(Express、Fastify、その他)を備えている必要があります。これをもって、KubernetesとDockerを使ってGoogle Cloudにデプロイし、このワークフローを最適化するためのサポートエコシステムがどのように役立つかを理解します。

これが、私たちが達成したいことを示す図です。

(ここに画像が表示されます)

その図の簡単な説明です。

  • Kubernetesクラスタ: Kubernetes環境全体を表します。
  • ノード: 仕事を実行する物理的または仮想マシン。この図では、2つのノード(ノード1とノード2)があります。
  • Fastifyポッド: Fastifyサーバーを実行するDockerコンテナを含んでいます。
  • Reactポッド: Reactアプリを実行するDockerコンテナを含んでいます。
  • Dockerコンテナ: アプリケーションを実行するコンテナ。ポッドによって管理されています。
  • Nginx: Reactアプリから生成された静的HTMLを提供するために使用されます。

この分野の仕事や探求で初心者のためのいくつかの技術的説明。

  • コンテナ: 軽量でスタンドアロンな、そして実行可能なソフトウェアパッケージで、ソフトウェアを実行するために必要な全てのもの(コード、実行環境、システムツール、ライブラリ、設定)が含まれています。コンテナは互いに、そしてホストシステムから隔離されています。ここでアプリケーションコードが実行されます。

  • ポッド: Kubernetesエコシステム内での最も小さい単位はポッドです。ポッドはクラスタ内の実行中のプロセスの単一インスタンスを表し、1つ以上のコンテナを含むことができます。同じポッド内のコンテナは同じネットワークIP、ポートスペース、ストレージを共有するため、localhostを通じて簡単に通信し、必要であればデータを共有することができます。

  • ノード: ノードはワーカーマシーン、VM、または物理コンピュータであり、ポッドを実行するホスティング環境として機能します。各ノードはマスターノードによって管理され、ポッドを実行するためのサービスが含まれています。ノードは複数のポッドをホストできます。

このアーキテクチャはどんな利点をもたらしますか?

  • 分離: ポッドはアプリケーション間の分離レベルを提供します。あるアプリケーションがクラッシュしたり問題があったりしても、別のポッドで実行されている他のアプリケーションに直接影響することはありません。

  • スケーラビリティ: アプリケーションを別々のポッドにデプロイすることで、各アプリケーションをその需要とリソース要件に基づいて個別にスケールすることができます。

  • リソース管理: Kubernetesでは、ポッドレベルでリソースリクエストと制限を設定することができます。各アプリケーションをそれぞれのポッドにデプロイすることにより、特定のニーズに応じたCPUとメモリ割り当てを微調整することができます。

  • バージョニングとアップデート: アプリケーションを別々のポッドにデプロイすることで、バージョニングやアップデートを管理するのが簡単になります。他のアプリケーションに影響を与えることなく、特定のアプリケーションをアップデートしたりロールバックしたりすることができます。

  • ログとモニタリング: アプリケーションが別々のポッドにある場合、それぞれのアプリケーションに特化したログとモニタリングを設定するのが簡単になり、トラブルシューティングやパフォーマンス分析に役立ちます。

  • セキュリティ: ポッドはセキュリティの分離レベルを提供します。アプリケーションを別々のポッドにデプロイすることで、それぞれのアプリケーションに特定のセキュリティポリシー、ネットワークポリシー、アクセスコントロールを適用できます。

それぞれのアプリケーションを別々のポッドにデプロイすることはベストプラクティスですが、ポッド内でコンテナを共有する必要があり、アプリケーションコンポーネントが密接に連携している場合には、マルチコンテナのポッド(1つのポッド内に複数のコンテナがある)が意味を持つ場合があります。ただし、そのようなシナリオはあまり一般的ではなく、特定の使用例のために使用されます。

このデプロイメントを達成するためのステップ

  • アプリケーションをDocker化する: ReactとFastifyアプリケーションの両方のDockerイメージを作成します。
  • コンテナレジストリにイメージをプッシュする: Google Container Registry(GCR)または選んだ別のコンテナレジストリにDockerイメージをプッシュします。
  • KubernetesデプロイメントとサービスのYAMLを作成する: 両方のアプリケーションのデプロイメントとサービス設定を定義します。
  • GKE上でデプロイする: kubectlを使ってGKE上でアプリケーションをデプロイします。

(AWS、Azureなどの他のクラウドプロバイダーにも適応できます)

達成するためのステップは以下の通りです。

  • アプリケーションをDocker化する
  • Google Container Registry(またはクラウドプロバイダーに応じたレジストリ)にイメージをプッシュする
  • KubernetesデプロイメントとサービスのYAMLを作成する。

以下は、サンプルのデプロイメントスクリプトです(クラスタの設定、セキュリティなどは、それぞれのクラウドプロバイダーに応じて設定する必要があります)。

Step 1 - アプリケーションをDocker化する

さらにステップを詳しく見てみましょう。

Dockerfile for React App

# React App Dockerfile
FROM node:14-slim AS build-stage

WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine AS production-stage
COPY --from=build-stage /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

ここではマルチステージビルドを使用して、ステージ1からの出力をさらに処理用に使っています。マルチステージビルドでは、各FROM命令は異なるベースイメージを使用することができ、ビルドの新しいステージが開始します。また、必要なものだけを最終イメージにコピーして、不要なものを後に残すことができます。ステージ名を指定しない場合は、デフォルトのステージインデックスを0から使用できます。

上記Dockerファイルの説明

  1. Node.jsのベースイメージ
FROM node:14-slim AS build-stage

後続の命令に使用されるイメージ입니다。

  1. 作業ディレクトリを設定する
WORKDIR /app

これによりコンテナ内の作業ディレクトリが'/app'に設定されます。以降のコマンドはこのディレクトリから実行されます。

  1. 'package.json' と 'package-lock.json' をコピー
COPY package*.json ./

このコマンドは、ホストマシンからコンテナの現在のディレクトリ('/app')に 'package.json' と 'package-lock.json' (存在する場合) の両方をコピーします。

  1. 依存関係をインストール
RUN npm install

これにより、'package.json' に指定されているNode.jsの依存関係がインストールされます。'package.json' をコンテナにコピー済みなので、このコマンドにより必要な依存関係がインストールされます。

  1. アプリケーションソースコードをコピー
COPY . .

これにより、ホストマシンの現在のディレクトリ(つまり、あなたの React アプリのソースコード)の全ての内容がコンテナ内の '/app' ディレクトリにコピーされます。

  1. Reactアプリケーションをビルド
RUN npm run build

これにより、package.json で指定された 'build' スクリプトが実行されます。これは、通常、Reactアプリを本番用にコンパイルおよびバンドルします(適切なコマンドについては、自分の package.json の scripts セクションを確認してください)。ここでは一般的に使用されるコマンドを元にしています。

  1. Nginxのベースイメージ
FROM nginx:alpine

Reactアプリをビルドした後、nginx:alpine ベースイメージで新しいステージを始めます。これはNginxがインストールされた軽量なイメージで、静的なReactアプリを提供するために使われます。

  1. NginxディレクトリにビルドされたReactアプリをコピー
COPY --FROM=build-stage /app/build /usr/share/nginx/html

これにより、ビルドされたReactアプリ(前のステージの /app/build ディレクトリ、build-stage として名付けられた)が Nginxで静的コンテンツを提供するためのデフォルトディレクトリ(/usr/share/nginx/html)にコピーされます。

  1. ポート80を公開
EXPOSE 80

これにより Docker にコンテナがポート 80 でリッスンしていることが通知されます。これは HTTP のデフォルトポートで、デフォルトで Nginx がコンテンツを提供するポートでもあります。このコマンドは、コンテナがどこでリッスンしているかを理解するためのドキュメンテーションのようなものです。

  1. Nginx起動
CMD ["nginx", "-g", "daemon off;"]

これはコンテナが開始したときに実行されるコマンドです。設定で 'daemon off' を持つ Nginxサーバーを開始し、Nginxがフォアグラウンドに残り、コンテナが実行され続けるようにします。

Dockerfile for Fastify API (必要に応じてExpressや他のフレームワークを使うことができます)

# Fastify API Dockerfile
FROM node:14-slim

WORKDIR /api
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 5000
CMD ["npm", "start"]

上のコマンドについては特に詳細な説明はしませんが、

こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/rajeshpillai/docker-kubernetes-and-the-rest-a-practical-1nop