はじめに
「ジャンルなしオンラインもくもく会 Advent Calendar 2025」の7日目の記事です。
本記事は、Kubernetesクラスタ構築シリーズの第5回です。前回の監視スタック構築に続き、今回はTLS証明書管理について学びます。
本シリーズの全体構成
前回のおさらい
本記事で学べること
- TLS終端の選択肢(LB / Ingress / Pod)
- cert-managerのインストールと設定
- 自己署名証明書によるHTTPS化
- IngressでのTLS設定
- homelabでの証明書管理
前提条件
- Day3までのクラスタ構築が完了していること
- Day4の監視スタックが稼働していること
1. TLS終端の選択肢
KubernetesでHTTPS通信を実現するには、いくつかの方法があります。
1.1 TLS終端の位置
1. LoadBalancer終端(AWS ALB, GCP HTTPS LB など)
2. Ingress終端 ★本記事で採用
3. Pod終端 (End-to-End 暗号化)
Pod終端が必要なケース
- 金融・医療: PCI-DSS, HIPAAなどコンプライアンス要件
- ゼロトラスト: クラスタ内部も信頼しないアーキテクチャ
- マルチテナント: 同一クラスタ内の他テナントからの盗聴防止
- Service Mesh: Istio/LinkerdのmTLSでPod間通信も暗号化
1.2 homelabでの選択
今回は Ingress終端を採用します。
理由
- 本番環境を意識: 自宅環境だから「IP直打ちでいいや」ではなく、本番同様の通信経路を構築
- 管理しやすい: cert-managerで証明書を自動管理
- パフォーマンス: 内部通信はHTTPで効率的
- 柔軟性: ホスト名ごとに異なる証明書を設定可能
2. cert-managerのインストール
2.1 cert-managerとは
cert-managerはKubernetesの証明書管理を自動化するツールです。
- 証明書の自動発行・更新
- Let's EncryptなどのACMEプロトコル対応
- 自己署名証明書のサポート
2.2 インストール
Kustomizeを使用してインストールします。
kubernetes/infrastructure/cert-manager/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: cert-manager
resources:
# cert-manager公式マニフェスト
- https://github.com/cert-manager/cert-manager/releases/download/v1.13.2/cert-manager.yaml
# ClusterIssuer設定
- cluster-issuer.yaml
labels:
- includeSelectors: true
pairs:
app.kubernetes.io/part-of: homelab-infra
適用
kubectl apply -k kubernetes/infrastructure/cert-manager/
2.3 インストール確認
kubectl get pods -n cert-manager
NAME READY STATUS RESTARTS AGE
cert-manager-5c994d7f66-6lhsx 1/1 Running 0 1m
cert-manager-cainjector-7f656b4cf5-d68wc 1/1 Running 0 1m
cert-manager-webhook-5f65679fbf-zlnq4 1/1 Running 0 1m
3. ClusterIssuerの設定
3.1 Issuer(発行者)の種類
| 種類 | 用途 | 特徴 |
|---|---|---|
| ClusterIssuer | クラスタ全体 | どのNamespaceからも利用可能 |
| Issuer | 特定Namespace | Namespace内のみ |
3.2 自己署名CAの構築
homelabでは自己署名CAを使用します。将来的にLet's Encryptに移行することも可能です。
kubernetes/infrastructure/cert-manager/cluster-issuer.yaml
# 1. 自己署名用のClusterIssuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-issuer
labels:
app.kubernetes.io/part-of: homelab-infra
spec:
selfSigned: {}
---
# 2. CA証明書を発行するためのClusterIssuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: homelab-ca-issuer
labels:
app.kubernetes.io/part-of: homelab-infra
spec:
ca:
secretName: homelab-ca-secret
---
# 3. CA証明書(selfsigned-issuerで発行)
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: homelab-ca
namespace: cert-manager
labels:
app.kubernetes.io/part-of: homelab-infra
spec:
isCA: true
commonName: homelab-ca
secretName: homelab-ca-secret
duration: 87600h # 10 years
renewBefore: 8760h # 1 year
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: selfsigned-issuer
kind: ClusterIssuer
group: cert-manager.io
適用
kubectl apply -f kubernetes/infrastructure/cert-manager/cluster-issuer.yaml
3.3 ClusterIssuerの確認
kubectl get clusterissuer
NAME READY AGE
homelab-ca-issuer True 1m
selfsigned-issuer True 1m
kubectl get certificate -n cert-manager
NAME READY SECRET AGE
homelab-ca True homelab-ca-secret 1m
4. IngressにTLSを設定
4.1 アノテーションによる自動証明書発行
cert-managerはIngressのアノテーションを監視し、自動的に証明書を発行します。
監視UIのIngressにTLS設定を追加
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus
namespace: monitoring
annotations:
cert-manager.io/cluster-issuer: homelab-ca-issuer # 追加
spec:
ingressClassName: nginx
tls: # 追加
- hosts:
- prometheus.homelab.local
secretName: prometheus-tls
rules:
- host: prometheus.homelab.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kube-prometheus-kube-prome-prometheus
port:
number: 9090
4.2 Helm values.yamlでのTLS設定
GrafanaはHelm chartで管理しているため、values.yamlで設定します。
kubernetes/infrastructure/monitoring/values.yaml
grafana:
ingress:
enabled: true
ingressClassName: nginx
annotations:
cert-manager.io/cluster-issuer: homelab-ca-issuer # 追加
hosts:
- grafana.homelab.local
tls: # 追加
- secretName: grafana-tls
hosts:
- grafana.homelab.local
4.3 適用
# Ingress の更新
kubectl apply -f kubernetes/infrastructure/monitoring/ingress.yaml
# Grafana の更新
helm upgrade kube-prometheus prometheus-community/kube-prometheus-stack \
-n monitoring \
-f kubernetes/infrastructure/monitoring/values.yaml
4.4 証明書の確認
kubectl get certificate -n monitoring
NAME READY SECRET AGE
alertmanager-tls True alertmanager-tls 1m
grafana-tls True grafana-tls 1m
prometheus-tls True prometheus-tls 1m
すべての証明書がREADY=Trueになっていれば成功です。
5. HTTPSアクセスの確認
5.1 CLIでの確認
# -k オプションで自己署名証明書を許可
curl -k https://grafana.homelab.local
curl -k https://prometheus.homelab.local
curl -k https://alertmanager.homelab.local
5.2 ブラウザでの確認
open https://grafana.homelab.local
open https://prometheus.homelab.local
open https://alertmanager.homelab.local
注意: 自己署名証明書のため、ブラウザで警告が表示されます。homelab環境では「続行」を選択してアクセスできます。
6. アーキテクチャ図
TLSを追加した現在のアーキテクチャ
7. 証明書のライフサイクル
7.1 自動更新
cert-managerは証明書の有効期限を監視し、自動的に更新します。
spec:
duration: 2160h # 90日
renewBefore: 360h # 15日前に更新
7.2 証明書の詳細確認
kubectl describe certificate grafana-tls -n monitoring
7.3 Secret の確認
kubectl get secret grafana-tls -n monitoring -o yaml
8. 将来的な拡張: Let's Encrypt
homelab が外部公開可能な場合、Let's Encrypt を使用できます。
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
9. まとめ
| 項目 | 内容 |
|---|---|
| TLS 終端 | Ingress Controller |
| 証明書管理 | cert-manager |
| Issuer | 自己署名CA(homelab-ca-issuer) |
| 自動更新 | cert-managerが自動で処理 |
Day5で達成したこと
- cert-managerのセットアップ
- 自己署名CAの構築
- 監視UIのHTTPS化
- 証明書の自動発行・管理
所感
- Week1では基盤の刷新としてTalos Linuxで構築し直し、証明書やLB周りも整理できた。Immutable OSのおかげでメンテナンスも楽になりそう
- 本番を意識して色々試した結果、当初3日の予定が5日に延びたのは御愛嬌。ネタも増えたので後日別シリーズとして検証頑張ります!
Week1完了!
参考リンク
- 本記事のサンプルコード(GitHub)
- cert-manager 公式ドキュメント
- cert-manager GitHub
- Let's Encrypt
- Secure end-to-end traffic on Amazon EKS using TLS certificate in ACM, ALB, and Istio(AWS Blog)
次回
Day6: HelmとKustomizeの使い分けガイド では、Kubernetesのパッケージ管理ツールを比較し、使い分けを学びます。