Cilium Gatewayと連動するcert-managerの導入でTLS証明書自動化
Cert-managerはTLS証明書自動管理に役立つツールで、KubernetesクラスタでのHTTPSウェブアクセスの用意が簡単にできるようになります。
先のポストではCilium Gatewayを構築し、whoamiサービスへのplain httpのアクセスを用意するところまでカバーしましたが、今回はcert-managerをセットアップしてhttpsアクセスを用意します。
ひとつ前のポスト:おうちKubernetesで構築するCilium Gateway
なお、しばらく前にCiliumではなくCalico, MetalLB, NGINX Gateway Fabricの組み合わせでcert-managerをセットアップしたときのポストもあるので興味がある方はご覧ください。
post on the previous cert-manager setup with calico & ngf
前提
- fluxcdとGitLabでGitOpsがセットアップ済み
- 次の5つのflux kustomizationsがセットアップ済み
-
./clusters/lab-hlv3
as flux-system created during bootstrap process -
./infrastructure/lab-hlv3/controllers
as infra-controllers -
./infrastructure/lab-hlv3/configs
as infra-configs -
./apps/lab-hlv3
as apps -
./sops/lab-hlv3
as sops
-
- ひとつ前のポストでカバーしたCilium Gatewayのセットアップ
- Gateway API v1.2.0のインストール
- Gateway作成、IPアドレス割り当て(本記事ではダミーIPアドレス192.0.2.83)、L2Announcement
- traefik/whoamiのdeployment, service, およびserviceとgatewayのhttp listenerを繋ぐhttprouteの作成
手順
- On infra-controllers
- Cert-managerをhelmでインストール
- On infra-configs
- Issuer作成
- Issuerと連動するようにGatewayコンフィグ更新
- Gatewayにhttps listener追加
- https listenerとwhoamiサービスを繋ぐHTTPRouteの作成
Cert-managerのhelmチャート
Cert-managerのhelmチャートが公開されているjetstack helmレポジトリを追加します。
# add helm repository
helm repo add jetstack https://charts.jetstack.io
レポジトリの中はこのような感じです。
# run helm repo update to update repository information
$ helm search repo jetstack
NAME CHART VERSION APP VERSION DESCRIPTION
jetstack/cert-manager v1.17.1 v1.17.1 A Helm chart for cert-manager
jetstack/cert-manager-approver-policy v0.19.0 v0.19.0 approver-policy is a CertificateRequest approve...
jetstack/cert-manager-csi-driver v0.10.2 v0.10.2 cert-manager csi-driver enables issuing secretl...
jetstack/cert-manager-csi-driver-spiffe v0.8.2 v0.8.2 csi-driver-spiffe is a Kubernetes CSI plugin wh...
jetstack/cert-manager-google-cas-issuer v0.9.0 v0.9.0 A Helm chart for jetstack/google-cas-issuer
jetstack/cert-manager-istio-csr v0.14.0 v0.14.0 istio-csr enables the use of cert-manager for i...
jetstack/cert-manager-trust v0.2.1 v0.2.0 DEPRECATED: The old name for trust-manager. Use...
jetstack/finops-dashboards v0.0.5 0.0.5 A Helm chart for Kubernetes
jetstack/finops-policies v0.0.6 v0.0.6 A Helm chart for Kubernetes
jetstack/finops-stack v0.0.5 0.0.3 A FinOps Stack for Kubernetes
jetstack/trust-manager v0.16.0 v0.16.0 trust-manager is the easiest way to manage TLS ...
jetstack/version-checker v0.8.6 v0.8.6 A Helm chart for version-checker
valuesファイル
helm show
コマンドを使って指定のバージョンのcert-manager helmチャートのvaluesファイルをダウンロードします。infra-controllers flux kustomizationよりインストールするので、そのあたりにディレクトリを用意してダウンロードしたファイルを格納しておきます。
いつでもダウンロードしなおせるファイルではありますが、私は編集前後のvaluesファイル両方ともGitOpsレポジトリに置いておきたいので以下のような操作になっています。
# on gitops repo
cd infrastructure/lab-hlv3/controllers/default-values
helm show values jetstack/cert-manager --version v1.17.1 > cert-manager-v1.17.1-values.yaml
cp cert-manager-v1.17.1-values.yaml ../values/cert-manager-values.yaml
# and edit values file at ./infrastructure/lab-hlv3/controllers/values/cert-manager-values.yaml
v1.17.1のcert-manager helmチャートのvaluesファイルへの変更はこのようになりました。
- cert-managerのCRDsインストール
- crds.enabled: true
- Gateway APIのサポートを有効に
- config.apiVersion: controller.config.cert-manager.io/v1alpha1
- config.kind: ControllerConfiguration
- config.enableGatewayAPI: true
- DNS01チャレンジ時の確認に利用するDNSサーバの指定
- dns01RecursiveNameservers: "1.1.1.1:53,1.0.0.1:53"
- dns01RecursiveNameserversOnly: true
fluxのhelm repoとhelm releaseマニフェストを用意するスクリプト
https://fluxcd.io/flux/guides/helmreleases/
fluxcdのGitOpsでhelmで何かをインストールする場合、手順としては (1) HelmRepository
を追加し、(2) そのレポジトリのチャートを指定したHelmRelease
を追加することで、fluxシステムが必要なものをプルし、インストールします。
以下はfluxcdのCRDsですが、これらのマニフェストを生成するためのfluxコマンドが用意されています(flux create source helm
やflux create helmrelease
など)。
$ kubectl api-resources | grep fluxcd
helmreleases hr helm.toolkit.fluxcd.io/v2 true HelmRelease
kustomizations ks kustomize.toolkit.fluxcd.io/v1 true Kustomization
alerts notification.toolkit.fluxcd.io/v1beta3 true Alert
providers notification.toolkit.fluxcd.io/v1beta3 true Provider
receivers notification.toolkit.fluxcd.io/v1 true Receiver
buckets source.toolkit.fluxcd.io/v1 true Bucket
gitrepositories gitrepo source.toolkit.fluxcd.io/v1 true GitRepository
helmcharts hc source.toolkit.fluxcd.io/v1 true HelmChart
helmrepositories helmrepo source.toolkit.fluxcd.io/v1 true HelmRepository
ocirepositories ocirepo source.toolkit.fluxcd.io/v1beta2 true OCIRepository
$ flux create source helm --help
The create source helm command generates a HelmRepository resource and waits for it to fetch the index.
For private Helm repositories, the basic authentication credentials are stored in a Kubernetes secret.
Usage:
flux create source helm [name] [flags]
Examples:
# Create a source for an HTTPS public Helm repository
flux create source helm podinfo \
--url=https://stefanprodan.github.io/podinfo \
--interval=10m
$ flux create helmrelease --help
The helmrelease create command generates a HelmRelease resource for a given HelmRepository source.
Usage:
flux create helmrelease [name] [flags]
Aliases:
helmrelease, hr
Examples:
# Create a HelmRelease with a chart from a HelmRepository source
flux create hr podinfo \
--interval=10m \
--source=HelmRepository/podinfo \
--chart=podinfo \
--chart-version=">4.0.0"
上は--help
出力の一部ですが、コマンド例をいくつか見る限り割と長いです。
チャートのバージョンなりvaluesファイルでパラメータを変更するとなると、その度にflux create
コマンドでマニフェストを作り直す必要があります。スクリプトを用意しておき、その手間を省けるようにしておきます。
以下がいつも私が用意しているHelmRepository
およびHelmRelease
生成用スクリプトのパターンです。二つのマニフェストを./infrastructure/lab-hlv3/controllers/cert-manager.yaml
という一つのファイルに出力します。infra-controllers flux kustomizationに含めるのはこのファイル一つだけとなります。Valuesファイルの中身を更新した時はスクリプトを走らせてcert-manager.yamlファイルを再生成するだけ、そしてバージョンを変更するときはスクリプト内のHelmRelease
より、--chart-version
の値を変更してスクリプトを走らせるだけで済みます。
# on gitops repo
mkdir infrastructure/lab-hlv3/controllers/scripts
cd infrastructure/lab-hlv3/controllers/scripts
# script to generate a file containing flux helmrepo and hr
cat <<'EOF' >cert-manager.sh
#!/bin/bash
# add flux helmrepo to the manifest
flux create source helm cert-manager \
--url=https://charts.jetstack.io \
--interval=1h0m0s \
--export >../cert-manager.yaml
# add flux helm release to the manifest including the customized values.yaml file
flux create helmrelease cert-manager \
--interval=10m \
--target-namespace=cert-manager \
--source=HelmRepository/cert-manager \
--chart=cert-manager \
--chart-version=v1.17.1 \
--values=../values/cert-manager-values.yaml \
--export >>../cert-manager.yaml
EOF
# run the script to generate the file
chmod u+x cert-manager.sh
./cert-manager.sh
cert-manager namespace
上で用意したHelmRelease
ですが、ターゲットnamespaceとして"cert-manager"を指定しています。--create-target-namespace
オプションをセットしていないので、namespaceは別途作っておく必要があります。
Namespaceの内容なりラベルなりをいじりたいといった時に、分けておけばHelmRelease
にはノータッチで作業できるのでこういう形にしています。
# ./clusters/lab-hlv3/namespaces/cert-manager.yaml
---
kind: Namespace
apiVersion: v1
metadata:
name: cert-manager
labels:
service: cert-manager
type: infrastructure
infra-controllers kustomization
最後に、fluxのinfra-controllers kustomizationを更新し、cert-managerのHelmRepository
およびHelmRelease
が含まれているcert-manager.yamlファイルを追加します。
# ./infrastructure/lab-hlv3/controllers/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- cm-placeholder.yaml
### crds
# gateway api
# version 1.2.0
- crds/gateway-api/standard/standard-install-v1.2.0.yaml
- crds/gateway-api/experimental/gateway.networking.k8s.io_tlsroutes-v1.2.0.yaml
### infra-controllers
- cert-manager.yaml
cert-managerインストール後の状態
インストール結果は以下のような感じで確認できると思います。
$ flux get all
NAME REVISION SUSPENDED READY MESSAGE
gitrepository/flux-system main@sha1:5883ff2a False True stored artifact for revision 'main@sha1:5883ff2a'
NAME REVISION SUSPENDED READY MESSAGE
helmrepository/cert-manager sha256:f3211071 False True stored artifact: revision 'sha256:f3211071'
NAME REVISION SUSPENDED READY MESSAGE
helmchart/flux-system-cert-manager v1.17.1 False True pulled 'cert-manager' chart with version 'v1.17.1'
NAME REVISION SUSPENDED READY MESSAGE
helmrelease/cert-manager v1.17.1 False True Helm install succeeded for release cert-manager/cert-manager-cert-manager.v1 with chart cert-manager@v1.17.1
NAME REVISION SUSPENDED READY MESSAGE
kustomization/apps main@sha1:5883ff2a False True Applied revision: main@sha1:5883ff2a
kustomization/flux-system main@sha1:5883ff2a False True Applied revision: main@sha1:5883ff2a
kustomization/infra-configs main@sha1:5883ff2a False True Applied revision: main@sha1:5883ff2a
kustomization/infra-controllers main@sha1:5883ff2a False True Applied revision: main@sha1:5883ff2a
$ kubectl get all -n cert-manager
NAME READY STATUS RESTARTS AGE
pod/cert-manager-cert-manager-cainjector-86cd99655f-44tn7 1/1 Running 0 2m19s
pod/cert-manager-cert-manager-d56b496b8-ssmmr 1/1 Running 0 2m19s
pod/cert-manager-cert-manager-webhook-54696f8b94-x2jxk 1/1 Running 0 2m19s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/cert-manager-cert-manager ClusterIP 10.96.243.72 <none> 9402/TCP 2m19s
service/cert-manager-cert-manager-cainjector ClusterIP 10.96.213.160 <none> 9402/TCP 2m20s
service/cert-manager-cert-manager-webhook ClusterIP 10.96.164.115 <none> 443/TCP,9402/TCP 2m19s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/cert-manager-cert-manager 1/1 1 1 2m19s
deployment.apps/cert-manager-cert-manager-cainjector 1/1 1 1 2m19s
deployment.apps/cert-manager-cert-manager-webhook 1/1 1 1 2m19s
NAME DESIRED CURRENT READY AGE
replicaset.apps/cert-manager-cert-manager-cainjector-86cd99655f 1 1 1 2m19s
replicaset.apps/cert-manager-cert-manager-d56b496b8 1 1 1 2m19s
replicaset.apps/cert-manager-cert-manager-webhook-54696f8b94 1 1 1 2m19s
$ kubectl api-resources | grep cert
challenges acme.cert-manager.io/v1 true Challenge
orders acme.cert-manager.io/v1 true Order
certificaterequests cr,crs cert-manager.io/v1 true CertificateRequest
certificates cert,certs cert-manager.io/v1 true Certificate
clusterissuers cert-manager.io/v1 false ClusterIssuer
issuers cert-manager.io/v1 true Issuer
certificatesigningrequests csr certificates.k8s.io/v1 false CertificateSigningRequest
cert-manager動作チェックスクリプト
https://cert-manager.io/docs/installation/kubectl/#verify
ここではスキップしますが、動作チェックスクリプトが用意されているので確認しておくと安心です。
Issuerの設定
https://cert-manager.io/docs/configuration/acme/
次にIssuerをセットアップしていきます。
The ACME Issuer type represents a single account registered with the Automated Certificate Management Environment (ACME) Certificate Authority server.
基本的に有効な証明書を取得するために必要なことは次のようなことになります:
- ACMEシステムにリクエストを提示する
- リクエストしている対象の名称に関するドメインの正当な所有者であることを証明する
私のドメインは以前Google DomainsからCloudflareへ移管しており、今回はCloudflare DNS01チャレンジで権利を証明するようIssuerをコンフィグします。
Cloudflare DNS01チャレンジ
First obtain the API token with appropriate scope, and then create issuer.
まずはCloudflareよりAPIトーケンを取得し、次にIssuerを作ります。
https://cert-manager.io/docs/configuration/acme/dns01/cloudflare/#api-tokens
https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.Issuer
ドキュメント記載の通り、APIトークンに付与する必要のある権限は次の通りです:
- permissions
- zone - dns - edit
- zone - zone -read
- zone resources
- include - all zones
APIトークンはsecretとしてkubernetesクラスタ上に作成し、Issuerはそのsecretを参照するようコンフィグすることになります。Secretのファイルは以下のようなファイルを用意してSOPS用ディレクトリに配置し、暗号化したものをcommit/pushします。
# ./sops/lab-hlv3/gateway/cloudflare-api-token-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api-token-secret
namespace: gateway
type: Opaque
stringData:
api-token: YOUR_API_TOKEN_HERE
次に、infra-configs用ディレクトリ配下にIssuerのファイルを用意します。apiTokenSecretRef
のところで先に作成したsecretを参照しています。
# ./infrastructure/lab-hlv3/configs/cert-manager/issuer.yaml
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: issuer
namespace: gateway
spec:
acme:
email: EMAIL_ADDR
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: issuer-account-key
solvers:
- dns01:
cloudflare:
email: EMAIL_ADDR
apiTokenSecretRef:
name: cloudflare-api-token-secret
key: api-token
selector:
dnsZones:
- "blink-1x52.net"
最後に、flux infra-configs kustomizationファイルに追加して出来上がりです。
# ./infrastructure/lab-hlv3/configs/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- cm-placeholder.yaml
# cilium gateway
- cilium/gateway.yaml
- cilium/ippools-cilium-gateway.yaml
- cilium/l2announcement-cilium-gateway.yaml
# cert-manager
# - cert-manager/cert-manager-test.yaml
# cloudflare dns01 issuer
- cert-manager/issuer.yaml
出来上がったIssuerの情報は以下のような形で確認できると思います。
# kubectl describe issuer issuer -n gateway
Status:
Acme:
......
Conditions:
Last Transition Time: 2025-03-31T01:21:13Z
Message: The ACME account was registered with the ACME server
Observed Generation: 1
Reason: ACMEAccountRegistered
Status: True
Type: Ready
Events: <none>
証明書のIssuerを利用するようCilium Gatewayを更新
Cilium Gatewayの設定を更新していきます。
Gatewayにhttp listenerを追加した際は、.spec.listeners[]
にhttp listenerを追加するだけでしたが、httpsの場合でも同じです。
以下のwhoami-kube-https
が今回追加するものです。
- hostnameはドメイン名も含めた宛先名であり、cert-managerが自動的に用意してくれる証明書はこの名前のものとなる
- 通信としてはSNIがここの値と合致するものがこのlistenerに処理されることになる
- portは443
- protocolはHTTPS
-
.spec.listeners[].tls
はplain httpではなかった新たな項目- "terminate"モードはgatewayがTLSオフロードし、後ろのサービスへは複合化されたplain httpが流れる形
-
.spec.listeners[].tls.certificateRefs
はcert-managerが最終的に有効な証明書を取得し、その証明書と鍵が格納されるsecretの名称であり、cert-managerを利用する際、既存のsecretを参照させるというものではなく好きに名付けてよい
.metadata
にも一つ重要な変更があります。annotationsのcert-manager.io/issuer
で指定している名称のIssuerが、このgatewayが連携する相手となります。ひとつ前の手順で作成した"issuer"がここでは指定されています。
# ./infrastructure/lab-hlv3/configs/cilium/gateway.yaml
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: cilium-gateway
namespace: gateway
annotations:
cert-manager.io/issuer: issuer
spec:
gatewayClassName: cilium
addresses:
- type: IPAddress
value: 192.0.2.83
listeners:
- name: whoami-kube-http
hostname: whoami-kube.lab.blink-1x52.net
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
gateway: cilium
- name: whoami-kube-https
hostname: whoami-kube.lab.blink-1x52.net
port: 443
protocol: HTTPS
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
gateway: cilium
tls:
mode: Terminate
certificateRefs:
- name: tls-whoami-kube
kind: Secret
namespace: gateway
何がどうなるのか
GatewayとIssuerが連携するよう更新し、有効なhttps listenerを追加すると、cert-managerが拾って署名された有効な証明書を取得するためのプロセスを回し始めます。
TLS証明書と鍵
最終的な状態を最初に見てみましょう。https listenerで指定したsecretを確認してみると、Kubernetes TLS secretが出来ていることが確認できます。
https://kubernetes.io/docs/concepts/configuration/secret/#tls-secrets
# kubectl get secret tls-whoami-kube -n gateway -o yaml
apiVersion: v1
kind: Secret
type: kubernetes.io/tls
metadata:
annotations:
cert-manager.io/alt-names: whoami-kube.lab.blink-1x52.net
cert-manager.io/certificate-name: tls-whoami-kube
cert-manager.io/common-name: whoami-kube.lab.blink-1x52.net
cert-manager.io/ip-sans: ""
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: Issuer
cert-manager.io/issuer-name: issuer
cert-manager.io/uri-sans: ""
creationTimestamp: "2025-03-31T02:08:36Z"
labels:
controller.cert-manager.io/fao: "true"
name: tls-whoami-kube
namespace: gateway
resourceVersion: "3969674"
uid: ec65b140-027b-4a75-91f5-a80709f36cc7
data:
tls.key: ...
tls.crt: ...
証明書取得までのプロセス
プロセスフロー図がcert-managerのドキュメントに載っています。
- https://cert-manager.io/docs/usage/gateway/#inner-workings-diagram-for-developers
- https://cert-manager.io/docs/usage/certificate/#inner-workings-diagram-for-developers
- https://cert-manager.io/docs/usage/certificaterequest/#inner-workings-diagram-for-developers
Gatewayにhttps listenerを追加すると、指定したhostnameの証明書が自動的にできていましたが、大まかには次のようなことが起こっています:
- "Certificate"が作成される
- 中身は空っぽといえる状態
- "CertificateRequest"が作成される
- "Order"が作成され、"Issuer"と連携し"Challenge"を立ち上げ、コンフィグ内容に従って(今回はCloudflareでのDNS01)チャレンジに対処し、証明書と鍵を取得する
- TLS証明書と鍵データで、
certificateRefs
で指定した名前のSecretが作成される - "Certificate"のステータスが更新される
Challengeの例
Challengeは処理が終わると消えます。以下は処理中のものをキャプチャできたときの出力です。
Statusを確認してください。このChallengeは"Presented: true"であり、"Processing: true"ですが、"State: pending"となっています。なぜならばDNS01チャレンジのためのDNSレコードの確認待ちだからです。
実はこれはcert-managerのhelm chart内、valuesファイルでdns01RecursiveNameservers
設定をする前の試行でキャプチャしたものでした。設定変更前は、私のkubernetesクラスタの場合はおうちラボ環境のDNSサーバに問い合わせする形になっており、"blink-1x52.net."ドメインの名前解決については外部のDNSサーバにまで問い合わせされることはなく、Challengeはこの状態でスタックしていました。
$ kubectl describe challenges -n gateway
Name: tls-whoami-kube-1-3711042244-1698055298
Namespace: gateway
Labels: <none>
Annotations: <none>
API Version: acme.cert-manager.io/v1
Kind: Challenge
Metadata:
Creation Timestamp: 2025-03-31T01:54:16Z
Finalizers:
acme.cert-manager.io/finalizer
Generation: 1
Owner References:
API Version: acme.cert-manager.io/v1
Block Owner Deletion: true
Controller: true
Kind: Order
Name: tls-whoami-kube-1-3711042244
UID: b3aee648-c1ab-4827-a9c3-42ef041f5456
Resource Version: 3962141
UID: 5121de47-99a5-4010-86a1-c991a40708f3
Spec:
Authorization URL: https://acme-v02.api.letsencrypt.org/acme/authz/xxx/xxx
Dns Name: whoami-kube.lab.blink-1x52.net
Issuer Ref:
Group: cert-manager.io
Kind: Issuer
Name: issuer
Key: KEY_HERE
Solver:
dns01:
Cloudflare:
API Token Secret Ref:
Key: api-token
Name: cloudflare-api-token-secret
Email: EMAIL_ADDR
Selector:
Dns Zones:
blink-1x52.net
Token: TOKEN_HERE
Type: DNS-01
URL: CHALLENGE_URL_HERE
Wildcard: false
Status:
Presented: true
Processing: true
Reason: Waiting for DNS-01 challenge propagation: DNS record for "whoami-kube.lab.blink-1x52.net" not yet propagated
State: pending
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Started 13m cert-manager-challenges Challenge scheduled for processing
Normal Presented 13m cert-manager-challenges Presented challenge using DNS-01 challenge mechanism
HTTPRouteの作成
次に、追加されたhttps listenerと既存のwhoamiサービスを繋ぐHTTPRouteを用意します。
Plain httpのHTTPRouteとほぼ同一です。唯一の変更点は.spec.parentRefs[].sectionName
で指している先がhttps listenerとなっていることだけです。
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: whoami-https
namespace: testbed
spec:
parentRefs:
- name: cilium-gateway
sectionName: whoami-kube-https
namespace: gateway
hostnames:
- "whoami-kube.lab.blink-1x52.net"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
結果
以下がcurlコマンドの結果です(IPアドレスはダミーの192.0.2.x)。
#$ curl -v https://whoami-kube.lab.blink-1x52.net
* Host whoami-kube.lab.blink-1x52.net:443 was resolved.
* ...
* Connected to whoami-kube.lab.blink-1x52.net (192.0.2.83) port 443
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519 / RSASSA-PSS
* ALPN: server did not agree on a protocol. Uses default.
* Server certificate:
* subject: CN=whoami-kube.lab.blink-1x52.net
* start date: Mar 31 01:10:01 2025 GMT
* expire date: Jun 29 01:10:00 2025 GMT
* subjectAltName: host "whoami-kube.lab.blink-1x52.net" matched cert's "whoami-kube.lab.blink-1x52.net"
* issuer: C=US; O=Let's Encrypt; CN=R11
* SSL certificate verify ok.
* Certificate level 0: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* Certificate level 1: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* Certificate level 2: Public key type RSA (4096/152 Bits/secBits), signed using sha256WithRSAEncryption
* using HTTP/1.x
> GET / HTTP/1.1
> Host: whoami-kube.lab.blink-1x52.net
> User-Agent: curl/8.5.0
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/1.1 200 OK
< date: Mon, 31 Mar 2025 05:09:34 GMT
< content-length: 339
< content-type: text/plain; charset=utf-8
< x-envoy-upstream-service-time: 0
< server: envoy
<
Hostname: whoami
IP: 127.0.0.1
IP: ::1
IP: 10.0.3.170
IP: fe80::e834:eff:fe1f:44f3
RemoteAddr: 10.0.3.174:41057
GET / HTTP/1.1
Host: whoami-kube.lab.blink-1x52.net
User-Agent: curl/8.5.0
Accept: */*
X-Envoy-Internal: true
X-Forwarded-For: IPADDR_OF_THE_HOST_EXECUTING_CURL
X-Forwarded-Proto: https
X-Request-Id: d3e749cd-70ac-4e83-ab61-28b132dc9a61
* Connection #0 to host whoami-kube.lab.blink-1x52.net left intact
終わりに
今回はcert-managerをセットアップしてTLS証明書管理自動化環境およびCilium Gateway経由のセキュアなウェブアクセスを用意しました。GitOpsでやることを考えるとdeploymentが一定にでき、運用も単純です。私のおうちラボの規模ではたいしたことないですが、大きなクラスタを運用するとなったらこの自動化環境の恩恵はなかなかのものだと思います。
前回も触れましたが繰り返さずにはいられません。クラスタ内のサービスへのHTTPSアクセスの追加作業がどれだけ簡単なことか。。手順は2つだけです。
- GatewayへのHTTPS listenerの追加
- listenerとサービスを繋ぐHTTPRouteの作成
Cert-managerは証明書の更新まで面倒を見てくれますので、あとは念のための定期的な確認・レポートスクリプトでも動かしておけば安心です。
Discussion