0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Kubernetes⑦(全7回)|kind|設計総合演習 — 「このアプリをk8sで設計して」に答える

0
Last updated at Posted at 2026-02-18

📁GitHubにコード公開GitHub: kubernetes_kind

シリーズ記事一覧

📑 目次

  1. この記事について
  2. この記事のゴール
  3. 前提条件
  4. お題:要件の確認
  5. 設計フェーズ:要件 → リソース設計
  6. 実装フェーズ:マニフェスト作成 → デプロイ
  7. 動作確認
  8. シリーズ総まとめ
  9. 次のステップ

1. この記事について

最終回です。
第1〜6回で整理してきた知識をすべて組み合わせて
1つのアプリケーションをk8sで設計・デプロイしてみました。

🍽️ これまで調理技術(各リソース)を個別に練習してきました。
最終回は「コース料理を設計して、フルで提供する」総合演習です。

  • 第1回:レストランの仕組みを理解した(k8sの世界観)
  • 第2回:スタッフを配置した(Pod / Deployment)
  • 第3回:お客さんが入れるようにした(Service)
  • 第4回:メニュー表とレシピ帳を整備した(ConfigMap / Secret)
  • 第5回:フロアを分けて入館証を発行した(Namespace / RBAC)
  • 第6回:トラブル対応マニュアルを整備した(運用)

今回:全部を組み合わせて、レストランを完全開店する。


2. この記事のゴール

この記事で書いていること:

  • 要件から必要なk8sリソースを洗い出す過程
  • 全体構成図の設計
  • 3層アプリをkindにデプロイして動作確認した話
  • 第1〜6回の知識がどこで使われたかの振り返り

3. 前提条件

項目 要件
前回の完了 第1〜6回の知識
クラスタ状態 kindクラスタが起動中
# WSL2 Ubuntu で実行

kubectl get nodes

4. お題:要件の確認

4-1. シナリオ

このように依頼されました:

「シンプルなWebアプリ(フロントエンド + API + DB)をKubernetesで設計・デプロイしてください」

4-2. 要件

項目 内容
アプリ構成 フロントエンド + API + DB の3層
フロントエンド 静的HTML配信(nginx)
API リバースプロキシ(nginx) → 将来的にアプリサーバーに差し替え可能
DB PostgreSQL
環境 開発環境(development)
非機能要件 フロントエンド/APIは2台以上、DBは1台
セキュリティ DBパスワードはSecretで管理

4-3. 設計のゴール(成功条件)

# 条件 テスト方法
1 フロントエンドにブラウザからアクセスできる port-forward → curl
2 フロントエンドからAPIに通信できる nginx設定でプロキシ
3 APIからDBに接続できる exec → psql
4 DBのパスワードがSecretで管理されている kubectl get secret
5 フロントエンド/APIが2台で冗長化されている kubectl get pods

5. 設計フェーズ:要件 → リソース設計

5-1. 必要なリソースの洗い出し

🍽️ 設計は「何を作るか」を決めるフェーズ。
コードを書く前に、必要なリソースを全て書き出します。

# リソース 用途 学んだ回
1 Namespace 開発環境を分離 第5回
2 ConfigMap (frontend) nginx設定ファイル 第4回
3 ConfigMap (api) nginx設定ファイル 第4回
4 ConfigMap (db) DB初期化設定 第4回
5 Secret DBパスワード 第4回
6 Deployment (frontend) フロントエンド × 2台 第2回
7 Deployment (api) API × 2台 第2回
8 Deployment (db) PostgreSQL × 1台 第2回
9 Service (frontend) フロントエンドへのアクセス 第3回
10 Service (api) APIへの内部アクセス 第3回
11 Service (db) DBへの内部アクセス 第3回

合計:11リソース

5-2. 全体構成図

凡例:
実線(→)= 通信フロー
点線(-.->)= ConfigMap・Secretの参照(マウント / 環境変数)

5-3. 通信の流れ

この3層アプリケーションの通信フローを、3つのフェーズに分けて見ていきます。
フェーズが進むにつれて経由する層が1つずつ増えていくことに注目してください。

5-3-1. フェーズ1:静的ページの取得(frontend層のみ)

5-3-2. フェーズ2:APIヘルスチェック(frontend → API)

5-3-3. フェーズ3:データ取得(frontend → API → DB)

5-4. デプロイ順序

依存関係があるため、デプロイには順序が重要です。

順序 リソース 理由
①最初 Namespace 全リソースの入れ物
②次 ConfigMap / Secret Deploymentが参照するため先に必要
③その次 DB Deployment + Service APIがDBに接続するため
④その次 API Deployment + Service フロントがAPIに接続するため
⑤最後 Frontend Deployment + Service 全ての依存先が揃ってから

🍽️ レストラン開店の準備順序:
食材倉庫(DB)→ キッチン(API)→ ホール(Frontend)。
倉庫がないのにキッチンは開けない。


6. 実装フェーズ:マニフェスト作成 → デプロイ

6-1. ディレクトリ構成(11リソース:①~⑪)

# WSL2 Ubuntu で実行

mkdir -p ~/k8s-handson/design-exercise
cd ~/k8s-handson/design-exercise

最終的なファイル構成:

~/k8s-handson/design-exercise/
├── 01-namespace.yaml
├── 02-db-secret.yaml
├── 03-db-configmap.yaml
├── 04-api-configmap.yaml
├── 05-frontend-configmap.yaml
├── 06-db-deployment.yaml
├── 07-db-service.yaml
├── 08-api-deployment.yaml
├── 09-api-service.yaml
├── 10-frontend-deployment.yaml
└── 11-frontend-service.yaml

🔰 Memo:
ファイル名に番号を付けたのは、デプロイ順序を示すためです。
kubectl apply -f でディレクトリごと適用すると、
ファイル名のアルファベット順で処理されるので、番号を付けておくと依存関係の順序が守られます。


6-2. ① Namespace

# 01-namespace.yaml
# Namespace = 開発環境のフロア

apiVersion: v1
kind: Namespace
metadata:
  name: k8s-web-app

💡ポイント:
Namespace は「フロアの仕切り」。
これ以降の全リソースに namespace: k8s-web-app を指定することで、
default と完全に分離される。


6-3. ② Secret(DBパスワード)

📂 design-exercise/
├── 01-namespace.yaml               ✅ ①
├── 02-db-secret.yaml               ← ② 🆕
├── 03-db-configmap.yaml            ← ③ 🆕
├── 04-api-configmap.yaml           ← ④ 🆕
├── 05-frontend-configmap.yaml      ← ⑤ 🆕
├── 06-db-deployment.yaml              ⑥
├── 07-db-service.yaml                 ⑦
├── 08-api-deployment.yaml             ⑧
├── 09-api-service.yaml                ⑨
├── 10-frontend-deployment.yaml        ⑩
└── 11-frontend-service.yaml           ⑪
# 02-db-secret.yaml
# Secret = レシピ帳(金庫保管)

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
  namespace: k8s-web-app
type: Opaque
stringData:
  POSTGRES_PASSWORD: "k8s-demo-password"
  # 本番では AWS Secrets Manager 等と連携が必須

🔑 ポイント:
stringData は平文で書けて便利だが、
kubectl get secret -o yaml で見ると data(base64)に自動変換されている。
本番では外部シークレットマネージャー連携が必須。


6-4. ③ ConfigMap(DB初期化)

# 03-db-configmap.yaml
# ConfigMap = DBの初期化設定

apiVersion: v1
kind: ConfigMap
metadata:
  name: db-config
  namespace: k8s-web-app
data:
  POSTGRES_DB: "webapp"
  POSTGRES_USER: "appuser"

  # DB初期化SQL
  init.sql: |
    CREATE TABLE IF NOT EXISTS health_check (
      id SERIAL PRIMARY KEY,
      status VARCHAR(20) DEFAULT 'ok',
      checked_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );
    INSERT INTO health_check (status) VALUES ('ok');

💡ポイント:
この ConfigMap は2つの役割を兼ねている。
POSTGRES_DB / POSTGRES_USER は環境変数として注入(envFrom)、
init.sql はファイルとしてマウント(volumeMounts)。
1つの ConfigMap でも注入方法が異なる点に注意。


6-5. ④ ConfigMap(API nginx設定)

# 04-api-configmap.yaml
# ConfigMap = APIのnginx設定

apiVersion: v1
kind: ConfigMap
metadata:
  name: api-config
  namespace: k8s-web-app
data:
  default.conf: |
    server {
        listen 80;
        server_name localhost;

        # ヘルスチェック
        location /health {
            return 200 '{"status": "ok", "service": "api"}';
            add_header Content-Type application/json;
        }

        # APIエンドポイント
        location / {
            return 200 '{"message": "Welcome to the API"}';
            add_header Content-Type application/json;
        }
    }

💡ポイント:
/health/ の2エンドポイントを定義。
将来アプリサーバー(Express, FastAPI等)に差し替える際は、
この ConfigMap を書き換えるだけで nginx 設定が切り替わる。


6-6. ⑤ ConfigMap(フロントエンド)

# 05-frontend-configmap.yaml
# ConfigMap = フロントエンドの設定(nginx設定 + HTML)

apiVersion: v1
kind: ConfigMap
metadata:
  name: frontend-config
  namespace: k8s-web-app
data:
  # nginx設定(/api へのリクエストをAPIサービスに転送)
  default.conf: |
    server {
        listen 80;
        server_name localhost;

        # 静的ファイルの配信
        location / {
            root /usr/share/nginx/html;
            index index.html;
        }

        # /api へのリクエストを api-svc に転送
        location /api/ {
            proxy_pass http://api-svc/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }

  # ─────────────────────────────────────────────
  # トップページのHTML(動作確認用の表示ページ)
  # ※ 学習の本質はここではなく、上の nginx設定 と Deployment の連携部分です
  # ※ HTML の中身をこのようにする必須性はありません
  # ─────────────────────────────────────────────
  index.html: |
    <!DOCTYPE html>
    <html lang="ja">
    <head>
      <meta charset="UTF-8">
      <title>k8s Web App</title>
      <style>
        body { font-family: sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
        h1 { color: #326CE5; }
        .status { padding: 15px; border-radius: 8px; margin: 10px 0; }
        .ok { background: #e8f5e9; border: 1px solid #4CAF50; }
        .info { background: #e3f2fd; border: 1px solid #2196F3; }
        code { background: #f5f5f5; padding: 2px 6px; border-radius: 3px; }
      </style>
    </head>
    <body>
      <h1>☸️ k8s Web App</h1>
      <p>Kubernetes設計・構築メモ — 第7回 総合演習</p>

      <div class="status ok">
        ✅ フロントエンドは正常に動作しています
      </div>

      <div class="status info">
        📡 APIの状態を確認するには:<br>
        <code>curl http://localhost:8080/api/health</code>
      </div>

      <h2>構成</h2>
      <ul>
        <li>🏪 Frontend: nginx(このページ)</li>
        <li>🍳 API: nginx(リバースプロキシ)</li>
        <li>🗄️ DB: PostgreSQL</li>
      </ul>
    </body>
    </html>

💡ポイント:
この ConfigMap は
default.conf(nginx設定)と index.html(HTML)の2ファイルを持つ。
Deployment 側で items を使い、
それぞれ別ディレクトリにマウントする(6-11 参照)。
nginx設定の proxy_pass http://api-svc/ が Service 名による名前解決の実例。


6-7. ⑥ DB Deployment

📂 design-exercise/
├── 01-namespace.yaml               ✅ ①
├── 02-db-secret.yaml               ✅ ②
├── 03-db-configmap.yaml            ✅ ③
├── 04-api-configmap.yaml           ✅ ④
├── 05-frontend-configmap.yaml      ✅ ⑤
├── 06-db-deployment.yaml           ← ⑥ 🆕
├── 07-db-service.yaml              ← ⑦ 🆕
├── 08-api-deployment.yaml             ⑧
├── 09-api-service.yaml                ⑨
├── 10-frontend-deployment.yaml        ⑩
└── 11-frontend-service.yaml           ⑪
# 06-db-deployment.yaml
# DB Deployment = 食材倉庫のスタッフ配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: db
  namespace: k8s-web-app
spec:
  replicas: 1                      # DBは1台(ステートフル)
  selector:
    matchLabels:
      app: db
  template:
    metadata:
      labels:
        app: db
    spec:
      containers:
        - name: postgres
          image: postgres:16
          ports:
            - containerPort: 5432

          # ConfigMapから一般設定を環境変数で注入
          envFrom:
            - configMapRef:
                name: db-config

          # Secretからパスワードを環境変数で注入
          env:
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: POSTGRES_PASSWORD

          # 初期化SQLをマウント
          volumeMounts:
            - name: init-sql
              mountPath: /docker-entrypoint-initdb.d
              readOnly: true

      volumes:
        - name: init-sql
          configMap:
            name: db-config
            items:
              - key: init.sql
                path: init.sql

ポイント解説:

フィールド なぜこの設定? 学んだ回
replicas 1 DBはステートフル。複数台にするにはレプリケーション設計が必要 第2回
envFrom.configMapRef db-config DB名・ユーザー名を ConfigMap から一括注入 第4回
env.secretKeyRef db-secret パスワードだけ Secret 経由で分離(セキュリティ) 第4回
volumeMounts /docker-entrypoint-initdb.d PostgreSQL が初回起動時に init.sql を自動実行するパス 第4回
volumes.configMap.items init.sql ConfigMap の特定キーだけをファイルとして取り出す 第4回

紐づけ図:

🍽️
DB Pod は「3方向から物資を受け取る調理場」。
ConfigMap から食材リスト(環境変数)と初期レシピ(init.sql)、
Secret から金庫の鍵(パスワード)を受け取り、Service が内線電話で繋ぐ。


6-8. ⑦ DB Service

# 07-db-service.yaml
# DB Service = 食材倉庫の内線電話(ClusterIP)

apiVersion: v1
kind: Service
metadata:
  name: db-svc
  namespace: k8s-web-app
spec:
  type: ClusterIP               # 内部からのみアクセス
  selector:
    app: db
  ports:
    - port: 5432
      targetPort: 5432

🍽️ 食材倉庫(DB)の内線電話。外部のお客さんには番号を教えない(ClusterIP)。

設定 理由
type ClusterIP DB は内部からのみアクセス。外部公開は不要
selector app: db DB Deployment の Pod を選択
port 5432 PostgreSQL のデフォルトポート

6-9. ⑧ API Deployment

📂 design-exercise/
├── 01-namespace.yaml               ✅ ①
├── 02-db-secret.yaml               ✅ ②
├── 03-db-configmap.yaml            ✅ ③
├── 04-api-configmap.yaml           ✅ ④
├── 05-frontend-configmap.yaml      ✅ ⑤
├── 06-db-deployment.yaml           ✅ ⑥
├── 07-db-service.yaml              ✅ ⑦
├── 08-api-deployment.yaml          ← ⑧ 🆕
├── 09-api-service.yaml             ← ⑨ 🆕
├── 10-frontend-deployment.yaml        ⑩
└── 11-frontend-service.yaml           ⑪
# 08-api-deployment.yaml
# API Deployment = キッチンのスタッフ配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
  namespace: k8s-web-app
spec:
  replicas: 2                      # APIは2台で冗長化
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: nginx
          image: nginx:1.25
          ports:
            - containerPort: 80

          # nginx設定をConfigMapからマウント
          volumeMounts:
            - name: api-conf
              mountPath: /etc/nginx/conf.d
              readOnly: true

      volumes:
        - name: api-conf
          configMap:
            name: api-config

ポイント解説:

フィールド なぜこの設定? 学んだ回
replicas 2 APIは冗長化。1台が落ちてもServiceが残りに振り分ける 第2回
image nginx:1.25 今回はnginxで代用。将来Express/FastAPI等に差し替え可能 第2回
volumeMounts /etc/nginx/conf.d ConfigMap の nginx 設定をファイルとしてマウント 第4回

💡DB Deployment との違い:
API には env / envFrom がない。  
設定はすべてファイルマウント(nginx.conf)で注入している。

紐づけ図:

🍽️
API Pod は「メニュー表(nginx設定)だけ受け取るシンプルなキッチン」。
DB Pod と比べると接続元が1つだけ。
— 設定の注入パターンが層によって異なる。


6-10. ⑨ API Service

# 09-api-service.yaml
# API Service = キッチンの内線電話(ClusterIP)

apiVersion: v1
kind: Service
metadata:
  name: api-svc
  namespace: k8s-web-app
spec:
  type: ClusterIP               # フロントエンドからの内部アクセス用
  selector:
    app: api
  ports:
    - port: 80
      targetPort: 80

🍽️
キッチン(API)の内線電話。
フロントエンドの nginx が proxy_pass http://api-svc/ でここに電話する。

設定 理由
type ClusterIP API は外部公開不要。Frontend からの内部通信のみ
selector app: api API Deployment の Pod(2台)にロードバランス
port 80 nginx のデフォルトポート

6-11. ⑩ Frontend Deployment

📂 design-exercise/
├── 01-namespace.yaml               ✅ ①
├── 02-db-secret.yaml               ✅ ②
├── 03-db-configmap.yaml            ✅ ③
├── 04-api-configmap.yaml           ✅ ④
├── 05-frontend-configmap.yaml      ✅ ⑤
├── 06-db-deployment.yaml           ✅ ⑥
├── 07-db-service.yaml              ✅ ⑦
├── 08-api-deployment.yaml          ✅ ⑧
├── 09-api-service.yaml             ✅ ⑨
├── 10-frontend-deployment.yaml     ← ⑩ 🆕
└── 11-frontend-service.yaml        ← ⑪ 🆕
# 10-frontend-deployment.yaml
# Frontend Deployment = ホールのスタッフ配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
  namespace: k8s-web-app
spec:
  replicas: 2                      # フロントエンドも2台で冗長化
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
        - name: nginx
          image: nginx:1.25
          ports:
            - containerPort: 80

          # nginx設定とHTMLをConfigMapからマウント
          volumeMounts:
            - name: frontend-conf
              mountPath: /etc/nginx/conf.d
              readOnly: true
            - name: frontend-html
              mountPath: /usr/share/nginx/html
              readOnly: true

      volumes:
        - name: frontend-conf
          configMap:
            name: frontend-config
            items:
              - key: default.conf
                path: default.conf
        - name: frontend-html
          configMap:
            name: frontend-config
            items:
              - key: index.html
                path: index.html

ポイント解説:

フィールド なぜこの設定? 学んだ回
replicas 2 フロントエンドも冗長化。Serviceが2台にロードバランス 第2回
volumeMounts (1つ目) /etc/nginx/conf.d nginx設定ファイル(proxy_pass含む)をマウント 第4回
volumeMounts (2つ目) /usr/share/nginx/html HTMLファイルをマウント(nginxのドキュメントルート) 第4回
volumes.items key指定で分離 1つの ConfigMap から default.confindex.html を別々のパスに配置 第4回

💡3つの Deployment の比較:
DB は envFrom + env + volumeMounts
API は volumeMounts のみ、
Frontend は volumeMounts × 2。
設定の注入パターンが層ごとに異なる点がポイント。

紐づけ図:

🍽️
Frontend Pod は「1つの引き出し(ConfigMap)から、
メニュー表(nginx設定)と看板(HTML)を別々に取り出して配置するホール」。
唯一の NodePort Service がお客さんの入口になる。


6-12. ⑪ Frontend Service

# 11-frontend-service.yaml
# Frontend Service = ホールの直通電話(NodePort)

apiVersion: v1
kind: Service
metadata:
  name: frontend-svc
  namespace: k8s-web-app
spec:
  type: NodePort                # 外部からアクセス可能
  selector:
    app: frontend
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080

🍽️
ホール(Frontend)の直通電話。
唯一の外部公開窓口(NodePort)。
お客さん(ブラウザ)はここに電話する。

設定 理由
type NodePort 唯一の外部公開 Service。ブラウザから直接アクセス
selector app: frontend Frontend Deployment の Pod(2台)にロードバランス
nodePort 30080 Node の 30080 番ポートで外部公開

💡3つの Service の type 比較:
DB = ClusterIP(内部のみ)、
API = ClusterIP(内部のみ)、
Frontend = NodePort(外部公開)。
外部に公開するのは入口の1つだけ — これが多層防御の基本。


6-13. 一括デプロイ

# ~/k8s-handson/design-exercise/ で実行

# 全マニフェストを一括適用(ファイル名順に処理される)
kubectl apply -f .

期待される出力:

namespace/k8s-web-app created
secret/db-secret created
configmap/db-config created
configmap/api-config created
configmap/frontend-config created
deployment.apps/db created
service/db-svc created
deployment.apps/api created
service/api-svc created
deployment.apps/frontend created
service/frontend-svc created

11リソースが一括で作成されました。

# 全リソースの状態を確認
kubectl get all -n k8s-web-app

期待される出力:

NAME                            READY   STATUS    RESTARTS   AGE
pod/api-xxxxxxxxx-xxxxx         1/1     Running   0          30s
pod/api-xxxxxxxxx-yyyyy         1/1     Running   0          30s
pod/db-xxxxxxxxx-zzzzz          1/1     Running   0          30s
pod/frontend-xxxxxxxxx-aaaaa    1/1     Running   0          30s
pod/frontend-xxxxxxxxx-bbbbb    1/1     Running   0          30s

NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/api-svc        ClusterIP   10.96.x.x       <none>        80/TCP         30s
service/db-svc         ClusterIP   10.96.x.x       <none>        5432/TCP       30s
service/frontend-svc   NodePort    10.96.x.x       <none>        80:30080/TCP   30s

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/api        2/2     2            2           30s
deployment.apps/db         1/1     1            1           30s
deployment.apps/frontend   2/2     2            2           30s

🍽️
全フロアにスタッフが配置され、電話回線も繋がりました。
レストラン開店。

💡kubectl get all は、
Pod / Service / Deployment / ReplicaSet を表示します。
ConfigMap・Secret・Namespace は表示されません。
確認するには個別コマンドが必要です。

# ConfigMap と Secret も確認
kubectl get configmap,secret -n k8s-web-app

7. 動作確認

7-1. フロントエンドにアクセス

# port-forward でフロントエンドにアクセス
kubectl port-forward service/frontend-svc 8080:80 -n k8s-web-app

別ターミナルで:

# トップページを確認
curl -s http://localhost:8080/

期待される出力: HTMLが返ってくれば成功です。

7-2. API経由でアクセス

# フロントエンドの /api/ がAPIに転送されるか確認
curl -s http://localhost:8080/api/health

期待される出力:

{"status": "ok", "service": "api"}

フロントエンド → API の通信が成功しました。

7-3. DBへの接続確認

# 別ターミナルで実行(port-forwardを止めない)

# DB Podに入ってpsqlで確認
kubectl exec -it deploy/db -n k8s-web-app -- psql -U appuser -d webapp -c "SELECT * FROM health_check;"

期待される出力:

 id | status |         checked_at
----+--------+----------------------------
  1 | ok     | 2026-xx-xx xx:xx:xx.xxxxxx
(1 row)

DBに初期データが入っています。
ConfigMapの init.sql が正しく実行されたようです。

7-4. Secret の確認

kubectl get secret db-secret -n k8s-web-app -o jsonpath='{.data.POSTGRES_PASSWORD}' | base64 --decode

期待される出力:

k8s-demo-password

7-5. 冗長性の確認(Self-healing)

# フロントエンドのPodを1つ削除
kubectl delete pod -l app=frontend \
  -n k8s-web-app \
  --field-selector=status.phase=Running \
  --grace-period=0 \
  --force 2>/dev/null | head -1

# すぐに確認
kubectl get pods -n k8s-web-app -l app=frontend --watch

2台体制が自動で復旧されることを確認したら Ctrl + C で終了。

7-6. 動作確認チェックリスト

# 確認項目 コマンド 結果
1 フロントエンド
にアクセス
curl localhost:8080/ ✅ HTML返却
2 API通信 curl localhost:8080/api/health ✅ JSON返却
3 DB接続 kubectl exec ... psql ✅ データ取得
4 Secret管理 kubectl get secret ✅ base64エンコード済み
5 冗長性 Pod削除 → 自動復旧 ✅ Self-healing

7-7. 後片付け

# Namespace ごと全て削除
kubectl delete namespace k8s-web-app

# port-forward を Ctrl+C で停止

8. シリーズ総まとめ

8-1. 第1〜7回の知識マッピング

今回のハンズオンで、どの回の知識がどこで使われたかを振り返ります。

学んだこと 今回の使用箇所
第1回 k8sの世界観、kind構築 kindクラスタで全体を動かした
第2回 Pod / Deployment 3つのDeployment(frontend/api/db)
第3回 Service ClusterIP × 2 + NodePort × 1
第4回 ConfigMap / Secret nginx設定、初期化SQL、DBパスワード
第5回 Namespace k8s-web-app で環境分離
第6回 トラブルシュート 動作確認時の調査コマンド

8-2. Docker Compose → k8s 最終対応表

Docker Compose Kubernetes 設計思想の違い
1ファイルで全管理 関心事ごとにリソースを分離 責任の分離
手動再起動 Self-healing 自律的な回復
スケール手動 Deployment + replicas 宣言的なスケール
ポート直結 Service(名前ベース) 抽象化
環境変数ベタ書き ConfigMap + Secret 設定の外部化
権限管理なし RBAC 最小権限の原則
単一ファイル Namespace 環境の論理分離

8-3. k8sの設計思想(まとめ)

7回を通じて見えてきたk8sの設計思想を3つにまとめます。

🍽️ チェーンレストラン経営の3原則

# 設計思想 比喩 具体例
1 宣言的管理 「常に3人体制」と宣言すれば、本部が勝手に維持する Deployment の replicas
2 関心事の分離 メニュー表、レシピ帳、食材倉庫は別々に管理する ConfigMap / Secret / Volume
3 疎結合 スタッフ(Pod)が入れ替わっても、代表電話(Service)は変わらない Service による抽象化

9. 次のステップ

9-1. このシリーズで学んだこと

✅ k8sの世界観(Docker Composeとの違い)
✅ コンテナ管理(Pod / ReplicaSet / Deployment)
✅ ネットワーク(Service / Ingress)
✅ 設定管理(ConfigMap / Secret / Volume)
✅ セキュリティ(Namespace / RBAC)
✅ 運用(ログ / 監視 / トラブルシュート)
✅ 総合設計(3層アプリのデプロイ)

9-2. 次の学習テーマ考察

優先度 テーマ 理由
⭐⭐⭐ Helm マニフェストのテンプレート化。実務では必須
⭐⭐⭐ PersistentVolume / PVC DBデータの永続化(今回は省略した部分)
⭐⭐⭐ Liveness / Readiness Probe ヘルスチェックの自動化
⭐⭐ HPA(Horizontal Pod Autoscaler) 負荷に応じた自動スケール
⭐⭐ EKS(AWS) クラウドでの本番k8s運用
⭐⭐ CI/CD + k8s GitOps(ArgoCD / Flux)
Istio / Service Mesh マイクロサービス間の通信制御
Operator パターン カスタムコントローラー

9-3. 最後に

🍽️ この7回のシリーズを通じて、
「個人経営の定食屋」の感覚から「チェーンレストランの設計」の視点に少しずつ変わってきた実感があります。
「なぜこう設計するのか」 という思考プロセスは、どんな技術が来ても応用できると思います。

このシリーズが、私と同じような立場の方のk8s学習の参考になればうれしいです。


(完結)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?