[k8s] cert-managerで管理している証明書を外部マシンで利用する
k8s の cert-manager で管理している証明書を k8s 外の マシン(WSL2) で利用してみました。
構成
Docker Desktop で稼働している k8s に cert-manager をインストールし自己署名証明書を作成します。
WSL2 状に nginx をインストールしその自己署名証明書で HTTPS で Listen させます。
ophum/k8s-secret-fs
cert-manager で管理している証明書を、k8s 外の VM で利用するためには「secret から証明書のデータを取得しコピーする」という方法が考えられます。
しかし以下のような課題があります。
-
証明書の更新時などに再度コピーする必要がある
-
利用する VM が複数ある場合は各 VM に配布する必要がある
そこで、secret のデータをファイルとしてマウントできるophum/k8s-secret-fsを実装しました。
使ってみる
cert-manager のインストール
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml
自己署名証明書
CA の作成
1apiVersion: cert-manager.io/v1
2kind: ClusterIssuer
3metadata:
4 name: selfsigned-issuer
5spec:
6 selfSigned: {}
7---
8apiVersion: cert-manager.io/v1
9kind: Certificate
10metadata:
11 name: my-selfsigned-ca
12spec:
13 isCA: true
14 commonName: my-selfsigned-ca
15 secretName: root-secret
16 privateKey:
17 algorithm: ECDSA
18 size: 256
19 issuerRef:
20 name: selfsigned-issuer
21 kind: ClusterIssuer
22 group: cert-manager.io
23---
24apiVersion: cert-manager.io/v1
25kind: Issuer
26metadata:
27 name: my-ca-issuer
28spec:
29 ca:
30 secretName: root-secret
自己署名証明書発行
1apiVersion: cert-manager.io/v1
2kind: Certificate
3metadata:
4 name: selfsigned.example.com
5spec:
6 subject:
7 organizations:
8 - MyOrg
9 countries:
10 - Japan
11 organizationalUnits:
12 - MyUnit
13 localities:
14 - Osaka
15 provinces:
16 - Osaka
17 commonName: selfsigned.example.com
18 duration: 8760h
19 dnsNames:
20 - selfsigned.example.com
21 secretName: selfsigned.example.com
22 issuerRef:
23 name: my-ca-issuer
24 kind: Issuer
25 group: cert-manager.io
26 privateKey:
27 algorithm: RSA
28 size: 2048
selfsigned.example.com
という名前で作成します。
apply すると以下のように証明書が作成され READY が True になります。
1hum@ryzen5pc:~/cert$ kubectl get cert
2NAME READY SECRET AGE
3my-selfsigned-ca True root-secret 117s
4selfsigned.example.com True selfsigned.example.com 2s
ついでに hosts に登録しておきます
1echo "127.0.0.1 selfsigned.example.com" | sudo tee -a /etc/hosts
k8s-secret-fs を起動する
k8s-secret-fs のバイナリをダウンロードします。
1wget https://github.com/ophum/k8s-secret-fs/releases/download/v0.2.0/k8s-secret-fs_0.2.0_linux_amd64.tar.gz -O - | tar xvz
設定ファイルを作成します。
1cat <<EOF > config.yaml
2kubeconfig: ${HOME}/.kube/config
3namespace: default
4secretName: selfsigned.example.com
5mountPoint: /mnt/k8s-secret-fs/
6EOF
マウントポイントを作成します。
1sudo mkdir -p /mnt/k8s-secret-fs
起動します。
1sudo ./k8s-secret-fs -config config.yaml &
マウントポイントを ls
で見てみると以下のように証明書ファイルが出来ていることが分かります。
1sudo ls /mnt/k8s-secret-fs
2ca.crt tls.crt tls.key
nginx で利用してみる
WSL2 上にマウントできたので、このファイルを nginx で利用してみます。
まずは nginx をインストールします。
1sudo apt install nginx
設定ファイルを作成します。
1cat <<EOF | sudo tee /etc/nginx/sites-available/ssl.conf
2server {
3 listen 443 ssl default_server;
4 listen [::]:443 ssl default_server;
5
6 server_name selfsigned.example.com;
7 root /var/www/html;
8 index index.html index.htm index.nginx-debian.html;
9
10 ssl_certificate /mnt/k8s-secret-fs/tls.crt;
11 ssl_certificate_key /mnt/k8s-secret-fs/tls.key;
12
13 location / {
14 try_files $uri $uri/ =404;
15 }
16}
17EOF
18sudo ln -s /etc/nginx/sites-available/ssl.conf /etc/nginx/sites-enabled/ssl.conf
nginx を起動します。(WSL2 では systemd が動作していないため直接起動)
1sudo nginx
curl してみる
https://selfsigned.example.com
に ca ファイルを指定して curl してみます。
1 sudo curl https://selfsigned.example.com/ -v --cacert /mnt/k8s-secret-fs/ca.crt
2* Trying 127.0.0.1:443...
3* TCP_NODELAY set
4* Connected to selfsigned.example.com (127.0.0.1) port 443 (#0)
5* ALPN, offering h2
6* ALPN, offering http/1.1
7* successfully set certificate verify locations:
8* CAfile: /mnt/k8s-secret-fs/ca.crt
9 CApath: /etc/ssl/certs
10* TLSv1.3 (OUT), TLS handshake, Client hello (1):
11* TLSv1.3 (IN), TLS handshake, Server hello (2):
12* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
13* TLSv1.3 (IN), TLS handshake, Certificate (11):
14* TLSv1.3 (IN), TLS handshake, CERT verify (15):
15* TLSv1.3 (IN), TLS handshake, Finished (20):
16* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
17* TLSv1.3 (OUT), TLS handshake, Finished (20):
18* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
19* ALPN, server accepted to use http/1.1
20* Server certificate:
21* subject: C=Japan; ST=Osaka; L=Osaka; O=MyOrg; OU=MyUnit; CN=selfsigned.example.com
22* start date: Aug 6 19:52:08 2022 GMT
23* expire date: Aug 6 19:52:08 2023 GMT
24* subjectAltName: host "selfsigned.example.com" matched cert's "selfsigned.example.com"
25* issuer: CN=my-selfsigned-ca
26* SSL certificate verify ok.
27> GET / HTTP/1.1
28> Host: selfsigned.example.com
29> User-Agent: curl/7.68.0
30> Accept: */*
31>
32* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
33* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
34* old SSL session ID is stale, removing
35* Mark bundle as not supporting multiuse
36< HTTP/1.1 200 OK
37< Server: nginx/1.18.0 (Ubuntu)
38< Date: Sat, 06 Aug 2022 20:31:58 GMT
39< Content-Type: text/html
40< Content-Length: 612
41< Last-Modified: Sat, 06 Aug 2022 20:25:14 GMT
42< Connection: keep-alive
43< ETag: "62eece2a-264"
44< Accept-Ranges: bytes
45<
46<!DOCTYPE html>
47<html>
48<head>
49<title>Welcome to nginx!</title>
50<style>
51 body {
52 width: 35em;
53 margin: 0 auto;
54 font-family: Tahoma, Verdana, Arial, sans-serif;
55 }
56</style>
57</head>
58<body>
59<h1>Welcome to nginx!</h1>
60<p>If you see this page, the nginx web server is successfully installed and
61working. Further configuration is required.</p>
62
63<p>For online documentation and support please refer to
64<a href="http://nginx.org/">nginx.org</a>.<br/>
65Commercial support is available at
66<a href="http://nginx.com/">nginx.com</a>.</p>
67
68<p><em>Thank you for using nginx.</em></p>
69</body>
70</html>
71* Connection #0 to host selfsigned.example.com left intact
Windows 側の hosts にも selfsigned.example.com
を登録することでブラウザでも証明書が反映されていることが確認できました。
さいごに
k8s-secret-fs を利用して cert-manager で作成した証明書を k8s 外のマシンで使うことができました。
これにより以下の課題を解決できました。
-
証明書の更新時などに再度コピーする必要がある
-
利用する マシン が複数ある場合は各マシンに配布する必要がある
証明書更新時は、証明書を利用しているソフトウェアの再起動(or 設定の再読み込み)で対応することができます。
また、証明書を cert-manager で一元管理できるというメリットが大きいと思います。