Docker & Kubernetes完全攻略 第6編:Kubernetes基礎 - 概念とアーキテクチャ
Docker & Kubernetes Complete Guide Part 6: Kubernetes Basics - Concepts and Architecture
序論:コンテナオーケストレーションの標準
これまでDockerを通じてコンテナを作成し管理する方法を学びました。しかし、実際のプロダクション環境では、数十、数百のコンテナを複数のサーバーにわたって運用する必要があります。この時、各コンテナを手動で管理することは事実上不可能です。
この第6編では、コンテナオーケストレーションの事実上の標準となったKubernetes(クーバネティス、K8s)の基礎概念とアーキテクチャを見ていきます。Kubernetesとは何か、なぜ必要なのか、そしてどのように構成されているかを理解すれば、クラウドネイティブ環境でのアプリケーション運用について全体的なイメージを描くことができます。
1. Kubernetesとは?
1.1 Kubernetesの定義
Kubernetesは、コンテナ化されたアプリケーションのデプロイ、スケーリング、管理を自動化するオープンソースプラットフォームです。ギリシャ語で「舵取り」または「パイロット」を意味し、コンテナという「貨物」を適切に運搬し管理する役割を果たします。
「K8s」という略称は、KとsのJ間に8文字(ubernete)があることに由来しています。
1.2 Kubernetesの歴史
- 2014年:Googleが内部で使用していたBorgシステムの経験を基にKubernetesをオープンソースとして公開
- 2015年:バージョン1.0リリース、Cloud Native Computing Foundation(CNCF)に寄贈
- 2018年:CNCFの最初の「卒業」プロジェクト
- 現在:コンテナオーケストレーションの事実上の標準として定着
1.3 Kubernetesが提供する機能
- サービスディスカバリとロードバランシング:DNS名やIPアドレスでコンテナを公開し、トラフィックを分散
- ストレージオーケストレーション:ローカルストレージ、クラウドストレージなどを自動でマウント
- 自動化されたロールアウトとロールバック:アプリケーションの変更を段階的にデプロイし、問題時は以前のバージョンにロールバック
- 自動ビンパッキング:リソース要求に応じてコンテナをノードに最適配置
- 自己修復(Self-healing):失敗したコンテナを再起動し、応答しないコンテナを置き換え
- シークレットと構成管理:機密情報を安全に保存し管理
2. なぜKubernetesが必要なのか?
2.1 Dockerだけでは不十分な理由
単一サーバーでいくつかのコンテナを運用する際はDockerだけで十分です。しかし、実際のプロダクション環境では次のような要件があります:
- 数百のコンテナを複数のサーバーに分散デプロイ
- トラフィック増加時に自動でコンテナ数を拡張
- コンテナ障害時の自動復旧
- 無停止デプロイ(Rolling Update、Blue-Green、Canary)
- コンテナ間のネットワークおよびストレージ管理
- リソースモニタリングとロギング
2.2 コンテナオーケストレーションの必要性
コンテナオーケストレーションとは、コンテナのデプロイ、管理、スケーリング、ネットワーキングを自動化することを意味します。オーケストラの指揮者が複数の楽器を調律するように、コンテナオーケストレーターは数多くのコンテナを調整します。
| 手動管理の問題点 | オーケストレーションの解決策 |
|---|---|
| サーバー障害時に手動復旧が必要 | 自動障害検知と復旧 |
| トラフィック増加時に手動スケーリング | 自動スケーリング(HPA、VPA) |
| デプロイ時にダウンタイム発生 | 無停止ローリングアップデート |
| コンテナ配置の最適化が困難 | 自動スケジューリングとビンパッキング |
| サービス間通信が複雑 | サービスディスカバリとロードバランシング |
2.3 Kubernetes vs 他のオーケストレーションツール
- Docker Swarm:Dockerネイティブオーケストレーション、シンプルだが機能が限定的
- Apache Mesos:汎用クラスター管理ツール、学習曲線が高い
- Nomad:HashiCorpのオーケストレーションツール、軽量
- Kubernetes:最も多くの機能、最大のエコシステム、事実上の標準
3. Kubernetesアーキテクチャ
Kubernetesクラスターは大きくControl Plane(コントロールプレーン)とWorker Node(ワーカーノード)で構成されます。
3.1 Control Plane(マスターノード)
Control Planeはクラスターの「頭脳」の役割を果たします。クラスターの状態を管理し、ワーカーノードで実行されるワークロードをスケジューリングします。
3.1.1 API Server(kube-apiserver)
Kubernetesのすべての通信の中心です。kubectlコマンド、他のコンポーネント、外部クライアントはすべてAPI Serverを通じてクラスターと対話します。
- RESTful API提供
- 認証(Authentication)、認可(Authorization)処理
- リクエストの検証
- etcdとの唯一の通信窓口
3.1.2 etcd
クラスターのすべての状態データを保存する分散キーバリューストアです。
- クラスター構成、状態、メタデータを保存
- 高可用性のため通常3つまたは5つのインスタンスで構成
- Raft合意アルゴリズムを使用
- クラスターバックアップ = etcdバックアップ
3.1.3 Scheduler(kube-scheduler)
新しく作成されたPodをどのノードに配置するかを決定します。
- リソース要件(CPU、メモリ)を考慮
- ノードの利用可能なリソースを確認
- アフィニティ/アンチアフィニティルールを適用
- Taint(テイント)とToleration(トレレーション)を処理
3.1.4 Controller Manager(kube-controller-manager)
クラスターの状態を望ましい状態に維持するさまざまなコントローラーを実行します。
- Node Controller:ノード状態のモニタリング
- Replication Controller:Pod数の維持
- Endpoints Controller:サービスとPodの接続
- Service Account Controller:アカウントとトークンの生成
3.1.5 Cloud Controller Manager(オプション)
クラウドプロバイダーのAPIと統合してクラウド固有の機能を管理します。
- ロードバランサーのプロビジョニング
- ストレージボリュームの管理
- ノード管理(クラウドインスタンス)
3.2 Worker Node
Worker Nodeは実際にアプリケーションコンテナが実行されるサーバーです。
3.2.1 kubelet
各ノードで実行されるエージェントで、Podのライフサイクルを管理します。
- API ServerからPod仕様(PodSpec)を受信
- コンテナランタイムにコンテナの作成/削除を要求
- コンテナ状態のモニタリングと報告
- ノード状態情報をAPI Serverに報告
3.2.2 kube-proxy
各ノードでネットワークプロキシの役割を果たします。
- Serviceの仮想IPを実際のPod IPにマッピング
- iptablesまたはIPVSルールの管理
- クラスター内部および外部トラフィックのルーティング
- ロードバランシング(ラウンドロビン)
3.2.3 Container Runtime
実際にコンテナを実行するソフトウェアです。
- containerd:Dockerから分離された業界標準ランタイム
- CRI-O:Kubernetes専用の軽量ランタイム
- Docker Engine:Kubernetes 1.24から直接サポート終了(dockershim削除)
3.3 アーキテクチャダイアグラム
┌─────────────────────────────────────────────────────────────────┐
│ CONTROL PLANE │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ API Server │ │ Scheduler │ │ Controller │ │
│ │ │ │ │ │ Manager │ │
│ └──────┬──────┘ └─────────────┘ └─────────────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ etcd │ │
│ │ (Key-Value) │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
│ (API通信)
│
┌─────────────────────────────────────────────────────────────────┐
│ WORKER NODE 1 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ kubelet │ │ kube-proxy │ │ Container │ │
│ │ │ │ │ │ Runtime │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Pod 1 │ │ Pod 2 │ │ Pod 3 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────────────────────────┘
4. Kubernetesコアオブジェクト
4.1 Pod
PodはKubernetesで作成・管理できる最小のデプロイ単位です。
Podの特徴:
- 1つ以上のコンテナを含む
- 同じPod内のコンテナはネットワークとストレージを共有
- 同じPod内のコンテナはlocalhostで通信
- 一般的に1つのメインコンテナ + 補助コンテナ(Sidecar)
- Podは一時的(ephemeral)- いつでも削除され再作成される可能性がある
# pod-example.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.24
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
4.2 Service
ServiceはPod集合に対する安定したネットワークエンドポイントを提供します。PodのIPは変わる可能性がありますが、ServiceのIP(ClusterIP)は固定されます。
Serviceタイプ:
- ClusterIP(デフォルト):クラスター内部からのみアクセス可能
- NodePort:各ノードの特定ポートで外部アクセスを許可
- LoadBalancer:クラウドロードバランサーを通じた外部アクセス
- ExternalName:外部DNS名をクラスター内部にマッピング
# service-example.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx # このラベルを持つPodにトラフィックを転送
ports:
- protocol: TCP
port: 80 # Serviceポート
targetPort: 80 # Podのコンテナポート
type: ClusterIP
4.3 Deployment
DeploymentはPodの宣言的アップデートを提供します。望ましい状態を定義すると、Deployment Controllerが実際の状態を望ましい状態に合わせます。
Deploymentの機能:
- Pod数(replicas)の管理
- ローリングアップデートとロールバック
- スケーリング(手動/自動)
- Podテンプレートの管理
# deployment-example.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3 # 3つのPodを維持
selector:
matchLabels:
app: nginx
template: # Podテンプレート
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.24
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # ローリングアップデート時に追加作成するPod数
maxUnavailable: 0 # ローリングアップデート時に使用不可のPod数
4.4 Namespace
Namespaceはクラスターを論理的に分離する仮想クラスターです。
デフォルトNamespace:
- default:特に指定なく作成されるリソースのデフォルトネームスペース
- kube-system:Kubernetesシステムコンポーネント用
- kube-public:すべてのユーザーが読み取れる公開リソース
- kube-node-lease:ノードハートビート情報を保存
# namespace-example.yaml
apiVersion: v1
kind: Namespace
metadata:
name: development
labels:
environment: dev
---
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
environment: prod
Namespaceの活用:
- 環境分離(dev、staging、production)
- チーム別リソース分離
- リソースクォータ(ResourceQuota)の適用
- ネットワークポリシー(NetworkPolicy)の適用
5. kubectl基礎
kubectlはKubernetesクラスターと対話するためのコマンドラインツールです。
5.1 kubectlのインストール
# macOS (Homebrew)
brew install kubectl
# Windows (Chocolatey)
choco install kubernetes-cli
# Linux (curl)
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
5.2 基本コマンド構造
kubectl [command] [TYPE] [NAME] [flags]
# 例
kubectl get pods # すべてのPodを取得
kubectl get pod nginx-pod # 特定のPodを取得
kubectl get pods -n kube-system # kube-systemネームスペースのPodを取得
kubectl get pods -o wide # 詳細情報を含めて取得
kubectl get pods -o yaml # YAML形式で出力
5.3 よく使うコマンド
リソース取得(get)
# Podリスト取得
kubectl get pods
kubectl get pods -A # すべてのネームスペース
# Serviceリスト取得
kubectl get services
kubectl get svc # 略語使用
# Deploymentリスト取得
kubectl get deployments
kubectl get deploy # 略語使用
# 複数リソースを同時に取得
kubectl get pods,services,deployments
# ラベルでフィルタリング
kubectl get pods -l app=nginx
# すべてのリソースを取得
kubectl get all
リソース詳細情報(describe)
# Pod詳細情報
kubectl describe pod nginx-pod
# Node詳細情報
kubectl describe node node-1
# Service詳細情報
kubectl describe service nginx-service
リソース作成(create、apply)
# YAMLファイルでリソース作成
kubectl apply -f deployment.yaml
# ディレクトリ内のすべてのYAMLファイルを適用
kubectl apply -f ./manifests/
# 命令的にリソース作成
kubectl create deployment nginx --image=nginx:1.24
kubectl create namespace my-namespace
# Dry-run(実際に作成せずにテスト)
kubectl apply -f deployment.yaml --dry-run=client
リソース修正(edit、patch、scale)
# リソースを直接編集(エディタが開く)
kubectl edit deployment nginx-deployment
# パッチで部分修正
kubectl patch deployment nginx-deployment -p '{"spec":{"replicas":5}}'
# スケール調整
kubectl scale deployment nginx-deployment --replicas=5
リソース削除(delete)
# 特定リソースを削除
kubectl delete pod nginx-pod
kubectl delete deployment nginx-deployment
# YAMLファイルで定義されたリソースを削除
kubectl delete -f deployment.yaml
# ラベルで削除
kubectl delete pods -l app=nginx
# ネームスペースとその中のすべてのリソースを削除
kubectl delete namespace development
ログとデバッグ
# Podログを取得
kubectl logs nginx-pod
kubectl logs nginx-pod -f # リアルタイムログストリーミング
kubectl logs nginx-pod --previous # 以前のコンテナログ
# マルチコンテナPodで特定コンテナのログ
kubectl logs nginx-pod -c sidecar
# Pod内部でコマンド実行
kubectl exec nginx-pod -- ls /usr/share/nginx/html
kubectl exec -it nginx-pod -- /bin/bash # インタラクティブシェル
# ポートフォワーディング(ローカルからPodにアクセス)
kubectl port-forward pod/nginx-pod 8080:80
kubectl port-forward service/nginx-service 8080:80
5.4 コンテキストとネームスペース管理
# 現在のコンテキストを確認
kubectl config current-context
# 利用可能なコンテキストリスト
kubectl config get-contexts
# コンテキスト切り替え
kubectl config use-context my-cluster
# デフォルトネームスペースを変更
kubectl config set-context --current --namespace=development
5.5 便利なkubectlプラグインとツール
# kubectx - コンテキストの素早い切り替え
brew install kubectx
kubectx # コンテキストリストと切り替え
kubens # ネームスペースリストと切り替え
# k9s - ターミナルUI
brew install k9s
k9s
# kubectl自動補完(bash)
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
# kubectlエイリアス設定
alias k='kubectl'
alias kgp='kubectl get pods'
alias kgs='kubectl get services'
6. 実習:最初のアプリケーションデプロイ
6.1 ローカルKubernetes環境設定
# Docker DesktopでKubernetesを有効化
# Settings > Kubernetes > Enable Kubernetes
# またはMinikubeを使用
brew install minikube
minikube start
# クラスター状態を確認
kubectl cluster-info
kubectl get nodes
6.2 Nginxをデプロイ
# 1. Deploymentを作成
kubectl create deployment nginx-demo --image=nginx:1.24
# 2. Deploymentを確認
kubectl get deployments
kubectl get pods
# 3. Serviceを作成(NodePortタイプ)
kubectl expose deployment nginx-demo --type=NodePort --port=80
# 4. Serviceを確認
kubectl get services
# 5. 接続テスト(Minikube)
minikube service nginx-demo
# 6. またはポートフォワーディング
kubectl port-forward service/nginx-demo 8080:80
# ブラウザで http://localhost:8080 にアクセス
6.3 スケーリングテスト
# Pod数を拡張
kubectl scale deployment nginx-demo --replicas=5
# Podを確認
kubectl get pods -o wide
# Pod数を縮小
kubectl scale deployment nginx-demo --replicas=2
6.4 ローリングアップデート
# イメージをアップデート
kubectl set image deployment/nginx-demo nginx=nginx:1.25
# ロールアウト状態を確認
kubectl rollout status deployment/nginx-demo
# ロールアウト履歴
kubectl rollout history deployment/nginx-demo
# ロールバック
kubectl rollout undo deployment/nginx-demo
6.5 クリーンアップ
# リソースを削除
kubectl delete deployment nginx-demo
kubectl delete service nginx-demo
# または一度に
kubectl delete deployment,service nginx-demo
7. Kubernetes学習リソース
7.1 公式ドキュメント
- Kubernetes公式ドキュメント:https://kubernetes.io/docs/
- Kubernetesチュートリアル:https://kubernetes.io/docs/tutorials/
- kubectlチートシート:https://kubernetes.io/docs/reference/kubectl/cheatsheet/
7.2 ローカル学習環境
- Minikube:ローカルKubernetesクラスター
- Kind(Kubernetes in Docker):Dockerコンテナでクラスターを実行
- Docker Desktop:内蔵Kubernetesサポート
- k3s:軽量Kubernetesディストリビューション
7.3 オンライン実習環境
- Katacoda:ブラウザベースKubernetes実習
- Play with Kubernetes:無料オンラインKubernetes環境
結論
この第6編では、Kubernetesの基礎概念とアーキテクチャを見てきました。重要なポイントをまとめると:
- Kubernetesとは:コンテナオーケストレーションの事実上の標準プラットフォーム
- アーキテクチャ:Control Plane(API Server、etcd、Scheduler、Controller Manager)とWorker Node(kubelet、kube-proxy、Container Runtime)で構成
- コアオブジェクト:Pod(最小デプロイ単位)、Service(ネットワークエンドポイント)、Deployment(宣言的Pod管理)、Namespace(論理的分離)
- kubectl:Kubernetesクラスターと対話するCLIツール
Kubernetesは最初は複雑に見えますが、その設計哲学である「宣言的構成」と「望ましい状態(Desired State)」を理解すれば、非常に強力で柔軟なツールであることがわかります。
次の編ではKubernetes実践を扱います。ConfigMapとSecretによる設定管理、Ingressによる外部トラフィックルーティング、PersistentVolumeによるデータ永続性など、実際の運用に必要な応用テーマを見ていきます。