shibomb

Kubernetes入門!Dockerの次へ、コンテナオーケストレーション基礎から実践チュートリアル

はじめに

こんにちは!プログラミングの世界へようこそ。コンテナ技術、特にDockerに触れたことがあるあなたなら、「たくさんのコンテナをどうやって管理すればいいんだろう?」という疑問を持ったことがあるかもしれません。そんなあなたのための次の一歩が、今回ご紹介する「Kubernetes(クーベネティス、通称k8s)」です。

この記事は、Kubernetesを初めて学ぶ方を対象とした、実践的な入門チュートリアルです。コンテナオーケストレーションという少し難しそうな概念を、身近な例え話を交えながら、実際に手を動かして理解していくことを目指します。読み終える頃には、あなたはKubernetesの基本的な仕組みを理解し、自分のアプリケーションをKubernetes上で動かすための第一歩を踏み出せるようになっているはずです。さあ、一緒に未来のスタンダード技術を学び始めましょう!

前提知識の確認

新しい技術を学ぶとき、どこから始めればいいか迷うことがありますよね。ここでは、Kubernetesを学ぶ上で持っているとスムーズに進められる知識と、今はまだ知らなくても大丈夫なことを整理しておきましょう。

必要な基礎知識

  • Dockerの基本操作: Dockerfile を使ってコンテナイメージをビルドし、docker run でコンテナを起動できる程度の知識があると理想的です。コンテナとは何か、なぜ便利なのかを体感していることが重要です。
  • コマンドライン操作: ターミナル(WindowsならPowerShellやWSL)での基本的なコマンド操作(cd, ls, mkdirなど)に慣れていると、学習がスムーズに進みます。

事前に理解しておきたい概念

  • コンテナ化のメリット: アプリケーションをコンテナにすることで、開発環境と本番環境の差異をなくし、どこでも同じように動かせる「ポータビリティ」の価値を理解していると、Kubernetesが解決しようとしている課題がより明確になります。
  • サーバーとネットワークの超基本: IPアドレスやポートといった言葉を聞いたことがあるレベルで大丈夫です。アプリケーションがどのように外部と通信するかの大まかなイメージがあれば十分です。

「分からなくても大丈夫」な部分

  • クラウドインフラの深い知識: AWS、GCP、Azureなどの具体的なサービスに関する詳細な知識は、現時点では必要ありません。まずは自分のPC上で動かすことから始めます。
  • 高度なネットワーク理論: 仮想ネットワークやファイアウォールの複雑な設定など、専門的な知識は追々学んでいけばOKです。心配せずに進みましょう。

環境構築:最初の一歩

理論だけでなく、実際に手を動かすことが習得への一番の近道です。まずは、あなたのPCにKubernetesを動かすための環境を作りましょう。

開発環境の準備(初心者向け解説)

Kubernetesは本来、複数のサーバーマシンで構成される「クラスター」を管理するものですが、学習用にはPC一台で動かせるツールがたくさんあります。今回は、多くの開発者が利用している「Docker Desktop」に内蔵されているKubernetes機能を使います。これなら、Dockerの環境があればすぐに追加でき、非常に手軽です。

必要なツールとインストール方法

  1. Docker Desktopのインストール: もし未インストールであれば、公式サイトからご自身のOS(Windows, Mac)に合ったインストーラーをダウンロードし、手順に従ってインストールしてください。

  2. Kubernetesの有効化: Docker Desktopを起動し、設定画面を開きます。

    • Mac: 画面上部のタスクトレイにある鯨のアイコンをクリックし、「Settings」または「Preferences」を選択します。
    • Windows: タスクトレイの鯨のアイコンを右クリックし、「Settings」を選択します。
  3. 設定画面の中から「Kubernetes」のタブを見つけ、「Enable Kubernetes」のチェックボックスをオンにして、「Apply & Restart」ボタンをクリックします。初回は必要なコンポーネントのダウンロードと起動に数分かかりますので、気長に待ちましょう。

  4. 動作確認: インストールが完了したら、ターミナルを開いて以下のコマンドを実行します。

    kubectl version --client

    バージョン情報が表示されれば、Kubernetesを操作するためのコマンドラインツールkubectl(キューブコントロールと読みます)の準備は完了です。次に、クラスターの状態も確認してみましょう。

    kubectl cluster-info

    クラスターの情報が表示されれば、あなたのPC上に小さなKubernetes環境が誕生した証です!

Docker Desktopの設定画面でKubernetesが有効化されている様子を示すイラスト。PCの画面上にKubernetes関連のアイコンやチェックボックスが表示されている様子を、親しみやすいタッチで表現する。

環境構築でつまずきやすいポイント

環境構築は最初の壁になりがちです。もし「Kubernetes is starting…」から進まないなどの問題が起きたら、以下の点を確認してみてください。

  • PCのリソース不足: KubernetesはそれなりにメモリやCPUを使います。Docker Desktopの設定で、割り当てるリソースを少し増やしてみましょう(メモリ4GB以上、CPU2コア以上が目安です)。
  • インターネット接続: 初回起動時には必要なコンテナイメージをダウンロードします。プロキシ環境下など、ネットワークに制限がある場合は設定を見直す必要があります。

焦らず一つずつ確認すれば、必ず解決できます。

基本概念の理解

コマンドを打つ前に、Kubernetesがどのような考え方で動いているのか、その「心」の部分を理解しておきましょう。

核となる考え方

Kubernetesの最も重要な考え方は「宣言的(Declarative)API」です。これは、「〜しろ」と命令する(命令的)のではなく、「〜という状態であってほしい」と理想の状態を宣言する、というアプローチです。

例えば、「コンテナAを起動しろ」と命令するのではなく、「コンテナAが常に3つ動いている状態にしておいて」と書いた設計図(マニフェストファイル)をKubernetesに渡します。するとKubernetesは、現在の状態と理想の状態を比較し、差があればそれを埋めるように自動で動いてくれるのです。もし1つコンテナが停止してしまっても、Kubernetesが「おっと、2つしか無いぞ。3つないと!」と検知して、自動的に新しいコンテナを起動してくれます。この「自律的に状態を維持する力」がKubernetesの最大の強みです。

身近な例での説明

これを大きなレストランの厨房に例えてみましょう。

  • あなた(開発者): 最高のレシピ(コンテナイメージ)を開発するシェフです。
  • Pod: 実際に料理(アプリケーション)が動いている個別の調理台です。コンテナが動く最小単位です。
  • Deployment: フロアマネージャーです。シェフから「このカレー(Pod)を常に3皿、準備万端の状態にしておいて」という指示書(マニフェストファイル)を受け取ります。彼は常に調理場を監視し、カレーが2皿になったらすぐに新しいものを作るよう指示を出します(自己修復機能・スケーラビリティ)。
  • Service: ウェイターです。お客さん(ユーザー)からの「カレーください」という注文を受け付け、準備ができているカレー(Pod)のどれか一つに案内します。どの調理台(Pod)のカレーが利用可能かを常に把握しており、お客さんが調理台の場所を意識する必要がないようにしてくれます(固定のアクセスポイント提供)。

このように、各役割が連携することで、大規模で複雑な厨房(システム)がスムーズに運営されるのです。

「なぜそうなるのか」の理解

  • なぜPodを直接使わず、Deploymentを使うのか?: もしシェフが直接調理台(Pod)に指示を出していたら、一つの調理台が使えなくなったときに、自分で代わりを探さなければなりません。マネージャー(Deployment)に任せることで、自動で復旧してくれ、スケール(数を増減)させるのも簡単になります。
  • なぜServiceが必要なのか?: 調理台(Pod)は、状況によって場所が変わったり(IPアドレスが変動)、入れ替わったりします。ウェイター(Service)という固定の窓口があることで、お客さんはいつでも迷わず料理にありつけるのです。

実践編:手を動かして学ぶ

活気のあるレストラン厨房のイラスト。シェフ、調理台(Pod)、フロアマネージャー(Deployment)、ウェイター(Service)それぞれの役割が視覚的に分かりやすく表現されている。

それでは、いよいよ実際に手を動かして、先ほどのレストランの例を再現してみましょう。簡単なWebサーバーであるNginxをKubernetes上で動かしてみます。

ステップ1: 基本的な実装

まず、フロアマネージャー(Deployment)への指示書となるマニフェストファイルを作成します。my-nginx-deployment.yamlという名前でファイルを作成し、以下の内容を記述してください。

# my-nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx-deployment # Deploymentの名前
spec:
  replicas: 2 # Podをいくつ維持したいか(今回は2つ)
  selector:
    matchLabels:
      app: nginx-server # このラベルが付いたPodを管理する
  template: # これがPodの設計図
    metadata:
      labels:
        app: nginx-server # Podに付けるラベル
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.25 # 使用するコンテナイメージ
        ports:
        - containerPort: 80 # コンテナが公開するポート

このファイルをKubernetesに適用します。ターミナルで以下のコマンドを実行してください。

kubecl apply -f my-nginx-deployment.yaml

deployment.apps/my-nginx-deployment createdと表示されれば成功です。状態を確認してみましょう。

kubectl get deployment

# 出力例
# NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
# my-nginx-deployment   2/2     2            2           10s

kubectl get pods

# 出力例
# NAME                                   READY   STATUS    RESTARTS   AGE
# my-nginx-deployment-6b7f8c5b4f-abcde   1/1     Running   0          20s
# my-nginx-deployment-6b7f8c5b4f-fghij   1/1     Running   0          20s

指示通り、2つのPodがRunning状態になっていることが確認できました!

ステップ2: 機能の拡張

次に、このNginxに外部からアクセスできるように、ウェイター(Service)を配置します。my-nginx-service.yamlという名前でファイルを作成してください。

# my-nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-nginx-service # Serviceの名前
spec:
  type: NodePort # 外部からアクセスできるServiceのタイプ
  selector:
    app: nginx-server # このラベルを持つPodにトラフィックを転送する
  ports:
    - protocol: TCP
      port: 80 # Serviceが受け付けるポート
      targetPort: 80 # 転送先のPodのポート
      # NodePort: 30007 # ポートを固定したい場合は指定(省略すると自動で割り当てられる)

このファイルを適用します。

kubectl apply -f my-nginx-service.yaml

状態を確認してみましょう。

kubectl get service

# 出力例
# NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
# my-nginx-service   NodePort    10.108.111.222   <none>        80:31234/TCP   5s
# kubernetes         ClusterIP   10.96.0.1        <none>        443/TCP        2d

PORT(S)の項目に80:31234/TCPのように表示されているのが確認できます。これは、「PCの31234番ポートへのアクセスを、このServiceの80番ポートに転送し、最終的にPodの80番ポートに届ける」という意味です。(ポート番号は環境によって異なります)

ブラウザで http://localhost:31234 にアクセスしてみてください。Nginxのウェルカムページが表示されれば大成功です!

ステップ3: 実用的な応用

Kubernetesの真価である、スケーラビリティと自己修復機能を試してみましょう。

まず、Podの数を3つに増やします。これはコマンド一つで実行できます。

kubectl scale deployment my-nginx-deployment --replicas=3

再度kubectl get podsを実行すると、Podが3つに増えていることが確認できます。次に、意図的にPodを1つ削除してみましょう。

# Podの名前はあなたの環境に合わせて書き換えてください
kubectl delete pod my-nginx-deployment-6b7f8c5b4f-abcde

削除した直後に、すばやくもう一度kubectl get podsを実行してみてください。古いPodがTerminating(終了中)になり、すぐに新しいPodがContainerCreating(作成中)またはRunningになっているのが分かります。これこそが、Deploymentが常にreplicas: 3という状態を維持しようとする自己修復機能です。

ステップ4: チーム開発を意識した改善

実際の開発では、DeploymentとServiceのように関連する設定はまとめて管理したいものです。YAMLファイルは---で区切ることで、1つのファイルに複数の定義を記述できます。

# my-nginx-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-server
  template:
    metadata:
      labels:
        app: nginx-server
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.25
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-nginx-service
spec:
  type: NodePort
  selector:
    app: nginx-server
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

このようにまとめておけば、kubectl apply -f my-nginx-app.yamlという一つのコマンドでアプリケーション全体をデプロイでき、管理がとても楽になります。

実際の開発現場での活用

学んだ基本が、実際の現場でどのように活かされているのかを見ていきましょう。

業務での使用例

  • マイクロサービスアーキテクチャ: 巨大な一つのアプリケーションを、機能ごとに小さなサービス(マイクロサービス)に分割して開発する際、それぞれのサービスをコンテナ化し、Kubernetesで管理するのは非常に一般的な構成です。
  • CI/CDパイプライン: Gitにコードがプッシュされたら、自動でテスト、コンテナイメージのビルド、そしてKubernetesへのデプロイまでを行うパイプラインを構築します。これにより、迅速かつ安全なリリースが可能になります。
  • 無停止デプロイ: Kubernetesのローリングアップデート機能を使えば、古いバージョンのコンテナを新しいものに一つずつ、ユーザーに影響を与えることなく入れ替えることができます。

チーム開発でのベストプラクティス

  • マニフェストファイルのバージョン管理: 今日作成したようなYAMLファイルは、アプリケーションのコードと同じようにGitで管理します。これにより、「いつ、誰が、どのようなインフラ構成の変更を行ったか」が明確になり、チームでの共同作業が容易になります(これをGitOpsと呼びます)。
  • 環境ごとの設定分離: 開発環境、ステージング環境、本番環境で、コンテナの数や利用するデータベースの設定は異なります。これらの違いをうまく管理するために、KustomizeやHelmといったツールがよく使われます。

保守性を意識した書き方

  • 意味のある名前とラベル: my-nginxのような名前ではなく、frontend-web-serverのように、役割が分かる名前を付けましょう。ラベルもapp: web, env: production, team: alphaのように、後から見て管理しやすいように設計することが重要です。
  • リソース要求と制限: 各コンテナが最低限必要とするCPUやメモリ、そして最大で使ってよい上限を設定することで、一つのコンテナがリソースを使い果たして他のコンテナに影響を与えるのを防ぎます。

よくあるつまずきポイントと解決策

学習中、エラーはつきものです。エラーは敵ではなく、学びのチャンスと捉えましょう。

初心者が陥りやすい問題

  • ImagePullBackOff: Kubernetesがコンテナイメージをダウンロードできない状態です。イメージ名が間違っている、プライベートなリポジトリへの認証情報がない、などの原因が考えられます。
  • CrashLoopBackOff: コンテナは起動したものの、すぐにクラッシュしてしまい、それを何度も繰り返している状態です。アプリケーション自体に問題があることが多いので、コンテナのログを確認する必要があります。
  • Podが Pending のまま: Podを配置するノード(サーバー)が見つからない状態です。多くは、クラスターのCPUやメモリが不足していることが原因です。

エラーメッセージの読み方

問題が起きたPodの「健康診断書」を見るコマンドがkubectl describeです。これで、なぜPodが正常に起動しないのか、詳細なイベント情報を確認できます。

kubectl describe pod <問題のPod>

出力の下の方にあるEventsセクションに、エラーの原因に関する重要なヒントが書かれていることが多いです。

デバッグの基本的な考え方

問題解決の基本は「切り分け」です。

  1. コンテナ単体で動くか?: docker runで、そのイメージがローカルで正常に起動するかを確認します。
  2. 設定は正しいか?: YAMLファイルのインデントがずれていたり、スペルミスがあったりしないか確認します。
  3. クラスタの状態は?: kubectl describe nodeで、クラスターのリソースに空きがあるかを確認します。

これらの情報を元に、一つずつ原因を潰していくことがデバッグの王道です。

継続的な学習のために

今日のチュートリアルは、Kubernetesという広大な世界への入り口に過ぎません。

次に学ぶべきこと

  • ConfigMap / Secret: 設定ファイルやパスワードなどの機密情報をコンテナから分離して管理する方法。
  • PersistentVolume / PersistentVolumeClaim: コンテナが消えてもデータを永続化させるための仕組み。
  • Ingress: 複数のサービスを、一つのIPアドレスとドメイン名でまとめて外部に公開するための高度なルーティング機能。
  • Helm: Kubernetesアプリケーションのパッケージマネージャー。複雑なアプリケーションの導入や管理を簡素化できます。

おすすめの学習リソース

  • 公式ドキュメント: Kubernetesの公式ドキュメントには、非常に優れたチュートリアルやコンセプトの説明があります。一次情報に触れる習慣は、エンジニアとしてとても大切です。
  • インタラクティブな学習サイト: ブラウザ上でコマンドを打ちながら学べるサービスもたくさんあります。ゲーム感覚で楽しみながら知識を定着させることができます。

コミュニティとの関わり方

技術学習は一人で抱え込むより、仲間と一緒の方が楽しく、効率的です。地域の勉強会やオンラインのフォーラム、SNSなどを活用して、分からないことを質問したり、他の人が何に困っているのかを覗いてみたりしましょう。教えることは最高の学習法でもあります。

まとめ:成長のための次のステップ

お疲れ様でした!本日は、コンテナオーケストレーションとは何かという概念から始まり、Kubernetesの基本であるDeploymentとServiceを実際に手を動かしながら学びました。そして、アプリケーションを宣言的に管理することのパワフルさ、自己修復やスケーリングといった機能の便利さを体感できたはずです。

Kubernetesは奥が深く、学ぶべきことはまだまだたくさんありますが、今日あなたが手に入れた知識と経験は、その冒険の確かな第一歩です。次のステップとして、ぜひご自身で書いた簡単なWebアプリケーションをDockerイメージにし、今日学んだ方法でKubernetes上にデプロイしてみてください。その小さな成功体験が、あなたをさらに大きく成長させてくれるはずです。これからも楽しみながら、学び続けていきましょう!

関連記事