CTS-KB

Dockerfile・Docker Compose・Kubernetes:単独イメージから外部運用へ

⏱ 約 3 分で読めます
#Kubernetes#GKE#Docker#Docker Compose#コンテナ

「Dockerfile → Docker Compose → Kubernetes」を、単独イメージを作る → ローカルで組み合わせてデバッグする → 外部で継続運用する流れと理解するのは、とてもよい入口です。

ただし、3つが順番に変換されるわけではありません。Docker ComposeをKubernetesへそのまま変換するのではなく、Dockerfileで作った同じイメージを、ComposeとKubernetesがそれぞれ別の実行定義で利用します。

Dockerfile・Docker Compose・Kubernetesの役割

3つの役割

要素主な役割成果物
Dockerfile1つのコンテナイメージを再現可能に作るイメージ
Docker Compose複数コンテナを主にローカルでまとめて起動するcompose.yaml
Kubernetesクラスタ上で配置、再起動、更新、公開を継続管理するマニフェスト

このシリーズでは、イメージの保管先にGitLab Container Registryを使い、すべて手作業でbuild、push、deployします。CI/CDは前提にしません。

1. Dockerfileでイメージを作る

次は、静的ファイルをNginxで配信する最小例です。

FROM nginx:alpine
COPY ./public /usr/share/nginx/html
EXPOSE 80
docker build -t example-app:local .
docker run --rm -p 8080:80 example-app:local

DockerfileにはOSパッケージ、アプリケーション、起動コマンドなど、コンテナ内に必要なものを書きます。DBパスワードやアクセストークンのような環境ごとの秘密値は焼き込みません。

2. Docker Composeでローカル結合を確認する

アプリケーションとDBなど、複数サービスの接続確認にはComposeが便利です。

services:
  app:
    build: .
    ports:
      - "8080:80"
    environment:
      DATABASE_HOST: db
    depends_on:
      - db

  db:
    image: postgres:alpine
    environment:
      POSTGRES_DB: example
      POSTGRES_USER: example
      POSTGRES_PASSWORD: LOCAL_DEVELOPMENT_ONLY
docker compose up --build
docker compose ps
docker compose logs -f app
docker compose down

depends_on は起動順を補助しますが、DBが問い合わせを受け付けられる状態まで保証するものではありません。アプリ側の再試行やhealthcheckも設計します。また、この例の値はローカル学習専用です。本物のパスワードをComposeファイルへコミットしません。

3. 同じイメージをレジストリへ置く

外部クラスタは開発PC内の example-app:local を取得できません。イメージにレジストリ名と固定タグを付け、手動でpushします。

docker tag example-app:local \
  registry.gitlab.com/GROUP/PROJECT/IMAGE:TAG

docker push registry.gitlab.com/GROUP/PROJECT/IMAGE:TAG

GitLabへの安全なログインと、GKEからのpull設定は第12回で扱います。latest のように実体が変わるタグより、リリース番号やコミット識別子など、どのイメージか追跡できるタグを使います。

4. Kubernetesで外部運用を宣言する

KubernetesではComposeの services をコピーするのではなく、目的ごとにオブジェクトを分けます。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: example-app
  template:
    metadata:
      labels:
        app: example-app
    spec:
      containers:
        - name: app
          image: registry.gitlab.com/GROUP/PROJECT/IMAGE:TAG
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: example-app
spec:
  selector:
    app: example-app
  ports:
    - port: 80
      targetPort: 80
  • Deploymentがコンテナの個数と更新を管理する
  • Serviceが作り直されるPodへ安定した宛先を与える
  • ConfigMapやSecretが環境差分を渡す
  • PersistentVolumeClaimが必要な永続データを扱う

Composeの1ファイルに近い情報を、Kubernetesでは責務別のAPIオブジェクトとして宣言します。

本番DBをPodに同居させるべきか

ローカルではComposeでDBを立てると便利ですが、GKE本番で同じ構成を無条件に再現する必要はありません。バックアップ、フェイルオーバー、ストレージ運用が必要なDBは、Cloud SQLなどのマネージドサービスを選ぶ方が運用しやすい場合があります。

「ComposeにあるからKubernetesにも全部載せる」ではなく、外部運用で誰が可用性を担うかをサービスごとに決めます。

よくある誤解

  • Dockerfileだけで複数サービスの運用構成まで定義できるわけではない
  • Docker ComposeはKubernetesの必須前工程ではない
  • KubernetesがDockerfileやイメージを置き換えるわけではない
  • コンテナ化しただけでデータが永続化されるわけではない
  • イメージ内へ秘密値を入れてはいけない

次回

外部運用を支えるクラスタ内部を、Control plane・data plane・etcdに分けて見ていきます。

参考資料