Kubernetesはコンテナオーケストレーションのデファクトスタンダードとなりましたが、初学者にとっては概念の多さが大きな壁です。本記事では、最も基本的な単位であるPodから出発し、実務で必須となるHelmチャートまでを段階的に解説します。
Podは、Kubernetesにおける最小のデプロイ単位です。1つ以上のコンテナをまとめたグループでして、同一Pod内のコンテナはネットワークとストレージを共有します。多くの場合、1つのPodには1つのコンテナを配置する構成が一般的です。
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:1.0.0
ports:
- containerPort: 8080
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
resourcesセクションでCPUとメモリの制限を設定することは、本番環境では必須です。これを忘れると、1つのPodがノード全体のリソースを食い潰す事態になりかねません。
実際の運用では、Podを直接作成することはほとんどありません。代わりにDeploymentリソースを使って、Podのレプリカ数やローリングアップデート戦略を宣言的に管理します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:1.0.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
readinessProbeとlivenessProbeの設定は見落としがちですが、安定したサービス運用には欠かせません。readinessProbeはトラフィックを受け入れ可能かを判定し、livenessProbeはコンテナの再起動要否を判定します。
Podを作成しただけでは、外部からアクセスできません。Serviceリソースでクラスタ内の通信経路を確立し、Ingressで外部からのアクセスを制御します。
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: my-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-service
port:
number: 80
Serviceには主にClusterIP、NodePort、LoadBalancerの3種類があります。本番環境ではClusterIP + Ingressの組み合わせが最も一般的です。
アプリケーションの設定値をコンテナイメージに含めてしまうと、環境ごとにイメージを再ビルドする必要が生じます。ConfigMapとSecretを使って設定を外部化しましょう。
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-config
data:
DATABASE_HOST: "db.example.com"
LOG_LEVEL: "info"
---
apiVersion: v1
kind: Secret
metadata:
name: my-app-secret
type: Opaque
data:
DATABASE_PASSWORD: cGFzc3dvcmQxMjM=
Secretの値はBase64エンコードされているだけで暗号化はされていない点に注意してください。本番環境では、Sealed SecretsやExternal Secrets Operatorなどを使った暗号化の仕組みを別途導入することを強く推奨します。
Kubernetesのマニフェストが増えてくると、環境ごとの差分管理やバージョニングが課題になります。Helmは、Kubernetesのパッケージマネージャーとして、テンプレート化されたマニフェスト群をチャートとしてまとめて管理できます。
# Helmのインストールと基本操作
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# チャートの検索とインストール
helm search repo nginx
helm install my-nginx bitnami/nginx --namespace web --create-namespace
# リリースの確認と管理
helm list --all-namespaces
helm status my-nginx -n web
自作のHelmチャートを作成する場合は、helm createコマンドでテンプレートを生成できます。
helm create my-app-chart
生成されるvalues.yamlに環境固有の設定値を定義し、テンプレートファイルからこれらの値を参照する構成です。ステージング環境用のvalues-staging.yaml、本番環境用のvalues-production.yamlを作成すれば、環境差分の管理が容易になります。
Kubernetesを本番運用する際に、私が特に重要だと考えるポイントを整理します。
Kubernetesは学ぶべきことが多いですが、Pod、Deployment、Service、Helmの基礎を押さえれば、実務で十分に活躍できます。段階的に知識を積み上げていきましょう。