Kubernetesとは
Kubernetesはコンテナオーケストレーションプラットフォームです。Kubernetesはコンテナ化されたアプリケーションのデプロイ、スケーリング、管理を自動化するためのオープンソースシステムです。
Kubernetesの主な機能:
- コンテナのオーケストレーション(配置、スケジューリング)
- アプリケーションのスケーリング(自動水平/垂直スケーリング)
- サービスディスカバリとロードバランシング
- ストレージオーケストレーション
- 自己修復機能(障害発生時の自動再起動や置き換え)
- シークレットと構成管理
- ローリングアップデートとロールバック
Kubernetesは「K8s」と略されることも多く、現代のクラウドネイティブアプリケーション開発とデプロイにおいて業界標準となっています。
なぜKubernetesを使うのかというと、自前で複数ホストと複数コンテナを管理するのが難しいから。
Docker RunやDocker Composeと比較したKubernetesの利点について
Docker Runは単一のコンテナを起動するための基本的なコマンドで、Docker Composeは複数コンテナで構成されるアプリケーションを単一ホスト上で管理するツールです。一方、Kubernetesはこれらと比較して以下の理由で使用されます:
スケーラビリティ
- Docker Run/Compose: 主に単一ホスト向けで、マルチホスト環境での管理は複雑
- Kubernetes: 複数ノードにわたる大規模クラスタを効率的に管理し、数千のコンテナまでスケール可能
高可用性
- Docker Run/Compose: 高可用性機能が限定的
- Kubernetes: ノード障害時の自動復旧、ポッドの再スケジューリング、自己修復機能を提供
デプロイ管理
- Docker Run/Compose: 複雑なデプロイ戦略の実装が困難
- Kubernetes: ローリングアップデート、カナリアデプロイ、ブルー/グリーンデプロイなどの高度な戦略をサポート
ロードバランシング
- Docker Run/Compose: 基本的なロードバランシングのみ
- Kubernetes: サービスディスカバリと内蔵ロードバランサーで複雑な通信をシームレスに管理
リソース管理
- Docker Run/Compose: リソース制限はあるが、動的配分は限定的
- Kubernetes: CPUやメモリの詳細な割り当て、QoS、オートスケーリング機能を提供
モニタリングと管理
- Docker Run/Compose: 基本的なログとモニタリング
- Kubernetes: 包括的なモニタリング、ロギング、アラート機能と豊富なエコシステム
Docker Run/Composeは小〜中規模の開発環境やシンプルなアプリケーションに適していますが、Kubernetesは本番環境での大規模デプロイ、高可用性要件、複雑なマイクロサービスアーキテクチャに適しています。
Minikubeを使用してローカル環境でKubernetesを動かす
Minikubeはローカル環境でKubernetesを簡単に実行するためのツールです。Kubernetesを試したり日々の開発への使用を検討するユーザー向けに、PC上のVM内でシングルノードのKubernetesクラスターを実行することができます。
brew install kubectl
brew install minikube
クラスターを起動
minikube start
ステータスを確認
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
クラスタのバージョンを確認
kubectl version
kubectlコマンドは、Kubernetesクラスターと対話するための公式コマンドラインツールです。
Client Version: v1.30.5
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.32.0
WARNING: version difference between client (1.30) and server (1.32) exceeds the supported minor version skew of +/-1
クラスタの正常性確認
kubectl cluster-info
kubectl get componentstatuses
クラスタのノード(物理/仮想マシン)一覧の表示
ノードとは、Kubernetesクラスター内の作業マシン(ワーカーマシン)のことです。
kubectl get nodes
クラスタのノード(物理/仮想マシン)詳細情報を表示
kubectl describe nodes
役立つツールとコマンド
-
watch''で囲んだコマンドを2秒ごとに実行してくれるbrew install watchwatch -t 'kubectl get pod' # 詳細な方 watch 'kubectl get pod,svc -o wide' -
batコマンドbrew install batbat pod.yaml bat Dockerfile
Podとは?
Podとは、Kubernetesにおける最小のデプロイ単位であり、1つ以上のコンテナをグループ化して管理するための概念です。
-
コンテナのグループ
通常は単一のアプリケーションを表す1つのメインコンテナと、オプションの補助的なコンテナ(サイドカー)で構成
同一Podの複数コンテナは常に同一ノード上でスケジュールされる -
共有リソース
Pod内のコンテナは同じネットワーク名前空間を共有(localhost経由で通信可能)
同じIPアドレスとポート空間を共有
共有ストレージボリュームにアクセス可能
Podは「論理的なホスト」と考えることができ、密接に関連するコンテナをまとめ、従来のVMに似た環境を提供します。ただし、Podは永続的な存在ではなく、再作成される可能性があるため、ステートレスな設計が推奨されます。
Podを使ってHello WorldをK8sにDeployしよう
-
Hello WorldのPodを起動
kubectl run --image gcr.io/google-samples/hello-app:1.0 --restart Never helloworld -
Podの表示
kubectl get podsNAME READY STATUS RESTARTS AGE helloworld 1/1 Running 0 28s -
Podないのコンテナのログを表示
kubectl logs helloworld -
Podのメタデータを表示
kubectl describe pod helloworld# Pod の基本識別情報 Name: helloworld # Pod の名前(この Pod を識別するための名前) Namespace: default # Pod が属するネームスペース(リソースをグループ分けする仕組み) Priority: 0 # Pod の優先度(0が最低、数値が高いほど優先される) Service Account: default # Pod が使用するサービスアカウント(権限管理用) # Pod が動作している物理的な場所 Node: minikube/192.168.49.2 # Pod が配置されているノード(サーバー)の名前とIPアドレス Start Time: Sun, 25 May 2025 17:31:07 +0900 # Pod が開始された日時 # Pod の分類・管理用ラベル Labels: run=helloworld # Pod に付けられたラベル(検索や管理に使用) Annotations: <none> # Pod に付けられた注釈情報(現在は未設定) # Pod の現在の状態 Status: Running # Pod の実行状態(Running = 正常に動作中) # ネットワーク関連の設定 IP: 10.244.0.6 # Pod に割り当てられた内部IPアドレス IPs: # Pod が持つIPアドレスの一覧 IP: 10.244.0.6 # 同上(複数IP対応のため配列形式) # Pod 内のコンテナ情報 Containers: # Pod に含まれるコンテナの一覧 helloworld: # コンテナの名前 Container ID: docker://bceef2d5e09710e621489bba7fdcda458ca29d66da27474bedefbabe09b14c06 # コンテナの一意識別子 Image: gcr.io/google-samples/hello-app:1.0 # 使用しているDockerイメージ Image ID: docker-pullable://gcr.io/google-samples/hello-app@sha256:173d532964a8cfd250b01878a46c18ccb303bcf21855b0fb9ac445bc486d1dbc # イメージの詳細識別子 Port: <none> # コンテナが公開するポート(未設定) Host Port: <none> # ホスト側のポート(未設定) State: Running # コンテナの実行状態 Started: Sun, 25 May 2025 17:31:07 +0900 # コンテナが開始された日時 Ready: True # コンテナがリクエストを受け付ける準備ができているか Restart Count: 0 # コンテナが再起動された回数(0 = 安定している) Environment: <none> # 環境変数の設定(現在は未設定) Mounts: # コンテナにマウントされたボリューム /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-zxqt6 (ro) # Kubernetes API へのアクセス用トークン(読み取り専用) # Pod の健全性チェック結果 Conditions: # Pod の各種状態チェック結果 Type Status # チェック項目とその結果 PodReadyToStartContainers True # コンテナ開始準備完了 Initialized True # 初期化完了 Ready True # サービス提供準備完了 ContainersReady True # 全コンテナが準備完了 PodScheduled True # ノードへの配置完了 # ストレージ関連の設定 Volumes: # Pod が使用するボリューム kube-api-access-zxqt6: # ボリューム名 Type: Projected (a volume that contains injected data from multiple sources) # 複数のデータソースを統合したボリューム TokenExpirationSeconds: 3607 # APIアクセス用トークンの有効期限(秒) ConfigMapName: kube-root-ca.crt # 使用するConfigMap名 ConfigMapOptional: <nil> # ConfigMapが必須かどうか DownwardAPI: true # Pod情報をファイルとして公開するか # リソース使用に関する設定 QoS Class: BestEffort # サービス品質クラス(BestEffort = 最低限の保証) # Pod配置に関する設定 Node-Selectors: <none> # 特定ノードを選択する条件(未設定) Tolerations: # ノードの問題を許容する設定 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s # ノードが準備未完了でも300秒間は実行継続 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s # ノードが到達不能でも300秒間は実行継続 # Pod に関するイベント履歴 Events: # Pod で発生したイベントの履歴 Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 85s default-scheduler Successfully assigned default/helloworld to minikube # Pod がノードに正常に配置された Normal Pulled 85s kubelet Container image "gcr.io/google-samples/hello-app:1.0" already present on machine # イメージが既にローカルに存在 Normal Created 85s kubelet Created container: helloworld # コンテナが正常に作成された Normal Started 85s kubelet Started container helloworld # コンテナが正常に開始された -
Pod内のコンテナの環境変数を定義
kubectl run --env TEST_ENV=hellow_world \ --image gcr.io/google-samples/hello-app:1.0 \ --restart Never helloworld以下のコマンドで設定したENVを確認できる。
kubectl describe pod helloworld -
Podを削除
kubectl delete pod helloworld -
ubuntuのイメージで作られたubuntuという名前のPodを作成し、起動し続ける。そしてコンテナに入る。
kubectl run ubuntu --image=ubuntu --restart Never -- sleep infinity # コンテナの中に入る kubectl exec -it ubuntu -- bash各パラメータの回詳細説明
kubectl run # 意味:新しいPodを作成して実行する基本コマンド # 類似:docker run(Dockerでコンテナを実行するのと似ている) ubuntu # 意味:作成するPodの名前 # 結果:Pod名が「ubuntu」になる # 確認:kubectl get pods で「ubuntu」という名前で表示される --image=ubuntu # 意味:使用するDockerイメージを指定 # ubuntu:Ubuntu Linux の公式イメージ # 取得元:Docker Hub から自動でダウンロード # 類似:docker run ubuntu と同じイメージを使用 --restart Never # 意味:Podが終了しても再起動しない設定 # Never:一度だけ実行(ジョブのような動作) # 対比:Always(常に再起動)、OnFailure(失敗時のみ再起動) -- sleep infinity # コンテナが終了せずに起動し続ける
Serviceとは?
ServiceはPodをクラスター内外に公開する静的IPを持ったL4ロードバランサーです。
クラスター内外からPodへの安定的なアクセスを提供できる仮想のIPアドレスをServiceに割り当てます。
いつ消えるかわからないPodのIPを覚えておく必要がなくなる。
ClusterIP Service
ClusterIPのServiceを使う利点は、いつ消えるかわからないPodIPを抽象化し、StaticIPを持ったProxyを前に置くことで:
- Podにアクセスする際に、Pod IPを知る必要がなくなる
- Podにアクセスする際に、ロードバランスしてくれる
ことです。
コマンド
-
'Helloworld'PodをClusterIPのServiceとしてクラスタ内部で公開
kubectl expose pod helloworld --type ClusterIP --port 8080 --name hellowworld-clusterip -
Serviceをリストアップ
kubectl get service -
クラスターないにCurlコンテナのPodを作成しシェル接続
kubectl run --restart Never --image curlimages/curl:7.68.0 -it --rm curl sh -
helloworld-clusteripClusterIP serviceへCurlでアクセステストcurl helloworld-clusterip:8080レスポンス
Hello, world! Version: 1.0.0 Hostname: helloworld
NodePort Serviceとは
NodePort Serviceを使う利点は、ClusterIPでは不可能だったクラスター街へのPodの公開を、NodeIPとNodePort経由で可能にすること。
-
helloworld-nodeportという名前で NodePortのServiceを作成。kubectl expose pod helloworld --type NodePort --port 8080 --name helloworld-nodeport -
外部からの接続確認
minikube service helloworld-nodeport|-----------|---------------------|-------------|---------------------------| | NAMESPACE | NAME | TARGET PORT | URL | |-----------|---------------------|-------------|---------------------------| | default | helloworld-nodeport | 8080 | http://192.168.49.2:30724 | |-----------|---------------------|-------------|---------------------------| 🏃 helloworld-nodeport サービス用のトンネルを起動しています。 |-----------|---------------------|-------------|------------------------| | NAMESPACE | NAME | TARGET PORT | URL | |-----------|---------------------|-------------|------------------------| | default | helloworld-nodeport | | http://127.0.0.1:52965 | |-----------|---------------------|-------------|------------------------| 🎉 デフォルトブラウザーで default/helloworld-nodeport サービスを開いています... ❗ Docker ドライバーを darwin 上で使用しているため、実行するにはターミナルを開く必要があります。以下で動作確認できた。
http://127.0.0.1:52965
NodePortのServiceでクラスター外にPodを公開できるが、NodeIPやNode Portを知らないといけないという問題がある。
LoadBalancer Serviceとは
クラウドプロバイダのL4ロードバランサーのDNSから、各ノードの特定のポートにRoutingしてPodにアクセスする。
- ロードバランサーのserviceを作成。
kubectl expose pod helloworld --type LoadBalancer --port 8080 --name helloworld-lb
LoadBalanserサービスにも問題があるので実際はL7のIngressを使う。
LoadBalancer:
- L4(TCP/UDP)レベル
- シンプルだが高コスト
- 1サービス = 1ロードバランサー
Ingress:
- L7(HTTP/HTTPS)レベル
- 複雑だが低コスト
- 1つのロードバランサーで複数サービス
L4 vs L7 の違い
L4(トランスポート層)
- TCP/UDP レベルの負荷分散
- IPアドレス + ポート番号で判断
- 中身を見ない(HTTPの内容は無視)
L7(アプリケーション層)
- HTTP/HTTPS レベルの負荷分散
- URL、ヘッダー、Cookieなどで判断
- 中身を理解(リクエストの詳細を解析)
具体例
L4の判断基準
192.168.1.100:80 → サーバーA
192.168.1.100:443 → サーバーB
# IPとポートのみで振り分け
L7の判断基準
example.com/api → APIサーバー
example.com/web → Webサーバー
example.com/admin → 管理サーバー
# URLパスで振り分け


