Kubernetes入門|基本概念とPod・Deploymentの作成を初心者向けに解説


はじめに

Dockerでコンテナを起動できるようになると、「複数のサーバーでコンテナを動かすにはどうするのか」「コンテナを一定数動かし続けるにはどうすればよいのか」といった疑問が出てきます。

こうしたコンテナの配置や管理を自動化するための仕組みが、Kubernetesです。

この記事では、Dockerを触ったことがある方に向けて、Kubernetesの基本概念から、NginxをPod・Deploymentとして作成し、状態を確認するところまでを解説します。

学習の流れは次のとおりです。

  1. Kubernetesの役割と基本用語を理解する
  2. ローカルのKubernetesクラスタへ接続する
  3. YAMLファイルからPodを作成する
  4. Deploymentで3つのPodを作成する
  5. ブラウザでNginxへ接続する
  6. Podの数を変更し、実習で作成したリソースを削除する

Dockerの基本操作を先に確認したい場合は、Docker入門をご覧ください。

1. Kubernetesとは

Kubernetesは、コンテナ化したアプリケーションの配置や実行状態の管理などを自動化する、オープンソースのプラットフォームです。「K8s」と略されることもあります。

例えば、Webアプリケーションを3つのPodで動かしたい場合、Kubernetesに「このアプリケーションのPodを3つ維持する」という設定を渡します。Kubernetesのコントローラーは現在の状態を確認し、設定された状態に近づけるために動作します。

このように、実現したい状態を設定で示す方法を、宣言的な管理と呼びます。

Dockerとの関係

DockerとKubernetesは、役割が異なります。

項目主な役割
Dockerイメージの作成や、コンテナの実行に使う
Kubernetesクラスタ上でコンテナ化したアプリケーションの配置や実行状態を管理する

KubernetesはDocker専用の管理ツールではありません。各Nodeでは、containerdなどのコンテナランタイムがコンテナを実行します。Dockerで作成した対応形式のイメージも利用できます。kubernetes.io

Kubernetesを使うメリット

  • 構成をファイルで管理できる: 使用するイメージやPodの数などをYAMLに記述できます。
  • 複数のNodeにアプリケーションを配置できる: KubernetesがPodの配置先を決定します。
  • 指定したPodの数を維持できる: Deploymentなどの管理下では、Podが失われた場合に代わりのPodを作成します。
  • アプリケーションの更新を管理できる: Deploymentを使うと、Podの設定変更に伴う更新を管理できます。

ただし、Podを増やすだけで高可用性が完成するわけではありません。Nodeの配置、アプリケーションの設計、データの保存方法なども関係します。

まずは、ローカル環境で「設定した状態に合わせてPodが作られる」という動きを理解しましょう。

2. クラスタと主要コンポーネント

Kubernetesの実行環境を、クラスタと呼びます。クラスタは、全体を管理するコントロールプレーンと、Podを実行するNodeなどで構成されます。

Nodeは、物理サーバーや仮想マシンなど、Kubernetesの管理下で動作する実行環境です。

コントロールプレーン

コントロールプレーンは、クラスタの状態を管理し、Podの配置などを決定します。古い資料では「マスター」と呼ばれることがあります。

コンポーネント主な役割
kube-apiserverクラスタを操作するためのAPIを提供する
etcdクラスタの状態や設定を保存する
kube-scheduler新しく作るPodの配置先Nodeを決める
kube-controller-manager各種コントローラーを動かし、現在の状態を望ましい状態へ近づける

Node側のコンポーネント

コンポーネント主な役割
kubeletNode上でPodの仕様に従ってコンテナの実行を管理する
コンテナランタイムコンテナを実際に実行する
kube-proxyServiceへの通信を実現するネットワーク処理を担う。構成によっては別の仕組みが代替する

最初から内部実装まで覚える必要はありません。「APIで設定を受け取り、配置を決め、Node上でコンテナを動かす」という役割分担を押さえてください。

ローカルのシングルノード環境では、コントロールプレーンとアプリケーションの実行を同じNodeが担うこともあります。Kubernetes

3. 最初に覚えたいリソース

Kubernetesでは、PodやDeploymentなどをリソースとして扱います。

リソース役割
NodePodを配置する実行環境
Namespaceクラスタ内のリソースを名前で区分する仕組み
Pod1つ以上のコンテナをまとめて実行する、基本となる単位
ReplicaSet指定した数のPodを維持する
DeploymentReplicaSetを管理し、Podの構成変更に伴う更新などを扱う
ServicePodへの安定した接続先などを提供する

Podはコンテナを実行する単位

Podには、1つ以上のコンテナが含まれます。同じPod内のコンテナは、ネットワークなどの実行環境を共有します。

今回の実習では、1つのPodにNginxのコンテナを1つ配置します。

Deployment・ReplicaSet・Podの関係

Deploymentを作成すると、その管理下にReplicaSetが作られ、ReplicaSetがPodの数を維持します。

例えば、Deploymentに replicas: 3 と指定すると、通常の作成直後の構成では、1つのReplicaSetが3つのPodを管理します。

アプリケーションを更新した場合などは、複数世代のReplicaSetが残ることがあります。DeploymentとReplicaSetが常に1対1とは限りません。

通常のアプリケーションの配置では、ReplicaSetを直接作成するより、Deploymentを使います。Kubernetes

Namespaceで実習用リソースを分ける

Namespaceは、PodやDeploymentなどの名前を区分するために使います。独立した別クラスタを作る仕組みではありません。また、NodeはNamespaceに所属しないリソースです。

この記事では、学習用に k8s-intro というNamespaceを作成します。

4. ローカルのKubernetes環境を準備する

この記事では、MacまたはWindowsでDocker Desktopを使用する環境を想定します。Docker Desktopが動作し、インターネットからコンテナイメージを取得できる状態で進めてください。

Docker DesktopでKubernetesを用意する

Docker Desktopの画面はバージョンによって異なります。現在の公式手順では、次の流れで作成します。

  1. Docker Desktopを起動する
  2. 「Kubernetes」の画面を開く
  3. 「Create cluster」を選択する
  4. クラスタの作成方式を選ぶ
  5. 「Create」を実行し、準備が完了するまで待つ

作成方式としてKubeadmとkindが表示される場合、最初はシングルノード構成のKubeadmで進められます。kindで作成したクラスタでも、この記事の基本操作は共通です。Docker Docs

古い画面では、設定内の「Kubernetes」から「Enable Kubernetes」を有効にする形式の場合があります。

画面が異なる場合は、Docker公式のKubernetes設定手順を確認してください。

kubectlが使えることを確認する

kubectl は、KubernetesのAPIを操作するためのコマンドラインツールです。

ターミナルで次のコマンドを実行します。

kubectl version --client

クライアントのバージョン情報が表示されれば、コマンド自体は利用できます。ただし、この確認だけではクラスタに接続できているかは分かりません。

kubectl が見つからない場合は、Kubernetes公式のツール導入手順を確認してください。

接続先を確認する

クラスタへの接続設定を、コンテキストと呼びます。まず、登録されている設定を確認します。

kubectl config get-contexts

Docker Desktopの docker-desktop が登録されていることを確認し、切り替えます。

kubectl config use-context docker-desktop
kubectl config current-context

次のように表示されれば、接続先はDocker Desktopです。

docker-desktop

続けて、クラスタへの接続とNodeの状態を確認します。

kubectl cluster-info
kubectl get nodes

kubectl cluster-info で接続先の情報が表示され、Nodeの STATUS が Ready になっていることを確認してください。Nodeの名前や数は、作成方式によって異なります。

以降は、学習用のローカルクラスタで実行します。

作業場所とNamespaceを作成する

作業用ディレクトリを作成します。

mkdir k8s-intro
cd k8s-intro

次に、実習用のNamespaceを作成します。

kubectl create namespace k8s-intro
kubectl get namespaces

一覧に k8s-intro があり、`STATUS` が Active なら準備完了です。

k8s-intro がすでに存在する場合は、以前の実習用かを確認してから使用してください。

5. マニフェストからPodを作成する

Kubernetesのリソースを定義するファイルを、マニフェストと呼びます。この記事ではYAML形式を使用します。

pod.yamlを作成する

エディターで pod.yaml を作成し、次の内容を保存してください。

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: k8s-intro
  labels:
    app: nginx-pod-demo
spec:
  containers:
    - name: nginx
      image: nginx:stable-alpine
      ports:
        - containerPort: 80

各項目の役割は次のとおりです。

項目役割
apiVersionこのリソースで使用するAPIのバージョン
kind作成するリソースの種類
metadata.nameリソースの名前
metadata.namespace作成先のNamespace
metadata.labelsリソースを識別・選択するためのラベル
spec実現したい状態の定義
spec.containersPod内で実行するコンテナの定義
image使用するコンテナイメージ
containerPortコンテナが使用するポートの情報

apiVersion は、手元のKubernetesのバージョン番号をそのまま書く項目ではありません。Podでは v1、後で作成するDeploymentでは apps/v1 を使います。

今回はNginx公式イメージの stable-alpine タグを使います。このタグの参照先は更新されるため、厳密な再現性が必要な場合はバージョンやダイジェストを固定してください。

また、`containerPort: 80` を記述するだけでは、PCの80番ポートや8080番ポートへ公開されません。ブラウザでの確認は、後ほど port-forward を使って行います。

Podを作成する

次のコマンドで、マニフェストをクラスタへ反映します。

kubectl apply -f pod.yaml

初回作成時の出力例です。

pod/nginx-pod created

-f は、読み込むファイルを指定するオプションです。今回はYAML内にNamespaceを記述しているため、Podは k8s-intro に作成されます。

Podの状態を確認する

kubectl get pods -n k8s-intro

-n は、操作対象のNamespaceを指定するオプションです。

起動が完了した場合の出力例です。経過時間などは環境によって異なります。

NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          30s
表示意味
NAMEPodの名前
READYReadyになった通常コンテナの数/通常コンテナの総数
STATUS現在の状態を示す表示
RESTARTSコンテナの再起動回数
AGE作成からの経過時間

起動直後は ContainerCreating になることがあります。状態の変化を続けて見る場合は、次のようにします。

kubectl get pods -n k8s-intro -w

確認を終えるときは Ctrl + C を押します。これは表示の監視を終了する操作であり、Podは停止しません。

配置先のNodeやPodのIPを確認するには、`-o wide` を付けます。

kubectl get pods -n k8s-intro -o wide

実習用のPodを削除する

確認できたら、単体で作成したPodを削除します。

kubectl delete -f pod.yaml
kubectl get pods -n k8s-intro

ほかにPodがなければ、次のように表示されます。

No resources found in k8s-intro namespace.

今回のPodにはReplicaSetなどの管理元がないため、削除しても代わりのPodは作成されません。YAMLをPCに保存してあるだけでは、自動的に再作成されない点を押さえてください。

6. Deploymentで3つのPodを作成する

次は、Deploymentを使ってNginxのPodを3つ作成します。

deployment.yamlを作成する

同じディレクトリに deployment.yaml を作成し、次の内容を保存してください。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: k8s-intro
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-deployment-demo
  template:
    metadata:
      labels:
        app: nginx-deployment-demo
    spec:
      containers:
        - name: nginx
          image: nginx:stable-alpine
          ports:
            - containerPort: 80

Podのマニフェストとの主な違いは、次の項目です。

項目役割
replicas: 3維持するPodの数を3つにする
selector.matchLabels管理対象のPodを選ぶ条件
template.metadata.labels作成するPodに付けるラベル
template.spec作成するPodの仕様

selector.matchLabels で指定した条件を、`template.metadata.labels` が満たす必要があります。今回の例では、両方を app: nginx-deployment-demo にそろえています。Kubernetes

また、Deployment自体の名前は metadata.name、作成されるPodのコンテナ名は template.spec.containers 内の name です。別の項目として読み分けてください。

Deploymentを作成する

kubectl apply -f deployment.yaml

初回作成時の出力例です。

deployment.apps/nginx-deployment created

作成直後は、イメージ取得やコンテナ起動に時間がかかる場合があります。次のコマンドで、Deploymentの展開完了を待ちます。

kubectl rollout status deployment/nginx-deployment -n k8s-intro --timeout=120s

完了時には、次のように表示されます。

deployment "nginx-deployment" successfully rolled out

120秒でタイムアウトしても、それだけでDeploymentが削除されたり、処理が取り消されたりするわけではありません。起動しない場合は、後述のエラー確認へ進んでください。

Deploymentを確認する

kubectl get deployments -n k8s-intro

出力例です。

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           1m

READY が 3/3 なら、指定した3つのPodがReadyになっています。`UP-TO-DATE` は現在のPodテンプレートに対応するPod数、`AVAILABLE` は利用可能と判定されたPod数です。

今回の設定では、HTTP応答を調べるReadiness Probeは定義していません。アプリケーションへのHTTP接続も、次の節で別途確認します。

ReplicaSetを確認する

kubectl get replicasets -n k8s-intro

出力例です。名前の末尾は環境やPodテンプレートによって異なります。

NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-7b6f8d9c5b   3         3         3       1m

ReplicaSetのマニフェストを直接作成していなくても、Deploymentによって作成されています。`DESIRED` は望ましいPod数、`CURRENT` は現在のPod数、`READY` はReadyになったPod数です。

Podを確認する

kubectl get pods -n k8s-intro -l app=nginx-deployment-demo

-l は、ラベルの条件で対象を絞り込むオプションです。

出力例です。Pod名の末尾は自動生成されるため、同じ名前にはなりません。

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-7b6f8d9c5b-2q7kl   1/1     Running   0          1m
nginx-deployment-7b6f8d9c5b-6m8np   1/1     Running   0          1m
nginx-deployment-7b6f8d9c5b-x4r9s   1/1     Running   0          1m

これで、Deployment・ReplicaSet・Podの3種類を確認できました。

単体で作成したPodとは異なり、ReplicaSetの管理下でPodが失われると、望ましい数を維持するために代わりのPodが作成されます。ただし、必要なNodeの空き容量やイメージ取得などの条件が満たされなければ、すぐに起動できるとは限りません。

7. ブラウザでNginxの動作を確認する

Podを作成しただけでは、PCの localhost:8080 へ自動的に公開されません。

今回は、動作確認用に kubectl port-forward を使います。

kubectl port-forward deployment/nginx-deployment 8080:80 -n k8s-intro

これは、Deploymentに対応するPodのうち1つを選び、PCの8080番ポートから、そのPodの80番ポートへ転送する操作です。3つのPodへの負荷分散を確認するコマンドではありません。Kubernetes

このターミナルを開いたまま、ブラウザで次のURLへアクセスします。

http://localhost:8080/

Nginxの初期ページが表示されれば、選択されたPod内のNginxがHTTPリクエストに応答しています。

確認が終わったら、コマンドを実行しているターミナルで Ctrl + C を押します。ポート転送は終了しますが、DeploymentやPodは動作を続けます。

8080番ポートが使用中の場合は、次のようにPC側の番号を変更してください。

kubectl port-forward deployment/nginx-deployment 8081:80 -n k8s-intro

この場合の接続先は http://localhost:8081/ です。

8. YAMLを変更してPodの数を変える

宣言的な管理を確認するため、Podの数を3つから2つへ変更してみましょう。

deployment.yaml の replicas を、次のように変更して保存します。ほかの項目はそのままで構いません。

  replicas: 2

同じファイルを、もう一度反映します。

kubectl apply -f deployment.yaml
kubectl rollout status deployment/nginx-deployment -n k8s-intro --timeout=120s
kubectl get deployments -n k8s-intro
kubectl get pods -n k8s-intro -l app=nginx-deployment-demo

変更が反映されると、Deploymentの READY が 2/2 になり、稼働するPodも2つになります。削除処理の途中では、一時的に Terminating のPodが表示される場合があります。

ファイルを編集しただけでは、クラスタの設定は変わりません。`kubectl apply` で設定を渡すと、コントローラーがその設定に合わせて動作します。

9. うまく動かないときの確認方法

クラスタへ接続できない

connection refused などが表示される場合は、Docker DesktopとKubernetesの起動状態を確認します。

kubectl config current-context
kubectl cluster-info
kubectl get nodes

接続先が docker-desktop か、Nodeが Ready になっているかを確認してください。

Podが見つからない

今回のPodは k8s-intro に作成しています。

kubectl get pods -n k8s-intro

-n を省略すると、現在のコンテキストに設定されたNamespaceが対象になります。通常は default ですが、設定によって異なります。

一覧に何も表示されない場合は、Namespaceの指定と kubectl apply の実行結果を確認してください。

PodがRunningにならない

まず、Pod名と状態を確認します。

kubectl get pods -n k8s-intro

次に、実際のPod名を指定して詳細を表示します。以下の POD_NAME は、一覧に表示された名前に置き換えてください。

kubectl describe pod POD_NAME -n k8s-intro

出力の末尾にある Events に、配置やイメージ取得などの失敗理由が表示されることがあります。

状態の例主に確認すること
PendingNodeの空き容量や配置条件を、Eventsで確認する
ContainerCreating作成処理を待ち、長引く場合はEventsを確認する
ErrImagePull / ImagePullBackOffイメージ名・タグ・認証・レジストリへの接続を確認する
CrashLoopBackOffコンテナが繰り返し終了する理由を、ログで確認する

コンテナのログは、次のように表示します。

kubectl logs POD_NAME -n k8s-intro

これらの表示だけで原因を断定せず、Eventsとログを読み合わせてください。

YAMLのエラーが出る

YAMLではインデントに半角スペースを使用します。タブを使っていないか、同じ階層の項目がそろっているかを確認してください。

Deploymentでは、`selector.matchLabels` とPodテンプレートのラベルの対応も確認します。今回の例では、両方を app: nginx-deployment-demo にします。

10. 実習で作成したリソースを削除する

まず、`port-forward` が動作している場合は Ctrl + C で終了します。

Deploymentを削除します。

kubectl delete -f deployment.yaml

通常、この操作でDeploymentが管理するReplicaSetと、そのReplicaSetが管理するPodも削除されます。

確認します。

kubectl get deployments,replicasets,pods -n k8s-intro

削除が完了していれば、対象のリソースは表示されません。

この記事の実習専用に作成したNamespaceで、ほかの用途に使っていないことを確認し、削除します。

kubectl delete namespace k8s-intro

Namespaceを削除すると、その中に残っているPodなどのリソースも削除対象になります。

PC上の pod.yaml と deployment.yaml は残ります。再度試す場合はNamespaceを作成し直し、必要なマニフェストを反映してください。

なお、これらは実習用リソースの削除であり、Docker DesktopのKubernetesクラスタ自体を停止する操作ではありません。

11. まとめ

この記事では、Kubernetesの基本概念を確認し、PodとDeploymentをマニフェストから作成しました。

  • Kubernetesは、コンテナ化したアプリケーションの配置や実行状態を管理する
  • マニフェストに「望ましい状態」を記述し、`kubectl apply` で反映する
  • Podは、コンテナをまとめて実行する基本単位
  • DeploymentはReplicaSetを管理し、ReplicaSetが指定した数のPodを維持する
  • kubectl get で状態を確認し、`describe` や logs で詳細を調べる
  • containerPort の指定だけでは、PC側へポートは公開されない
  • port-forward を使うと、動作確認用にPodへ接続できる

まずは、Podを1つ作成する場合と、Deploymentで複数のPodを管理する場合の違いを押さえてください。

次は、Podへの安定した接続先を用意するServiceを学ぶと、アプリケーションの起動と通信経路の役割をつなげて理解できます。

参考資料

※参考PDFの古い名称・イメージ指定などは見直し、環境準備は現在の公式手順で補足しています。実習用Namespaceの作成、ポート転送、Pod数の変更、エラーの確認、削除手順は、本稿の実習補足です。


コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です