これまでIngressにAmbassador Edge Stack(AES)を使っていたが、使用するのにライセンスが必要になったため、Traefik Proxyに変更してみた。下記等のサイトを参考に導入。
https://www.vultr.com/docs/how-to-deploy-a-secure-nginx-website-on-vultr-kubernetes-engine/
https://www.vultr.com/docs/how-to-secure-a-vke-cluster-using-traefik-certmanager-and-lets-encrypt/
Installing Cert-manager
cert-manager GitHub repositoryを参照して、最新版をインストール。
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.2/cert-manager.yaml
インストール確認。
kubectl -n cert-manager get all
【実行結果例】
NAME READY STATUS RESTARTS AGE
pod/cert-manager-7d75f47cc5-k77gw 1/1 Running 0 17h
pod/cert-manager-cainjector-c778d44d8-v6v55 1/1 Running 0 17h
pod/cert-manager-webhook-55d76f97bb-zhxb5 1/1 Running 0 17h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/cert-manager ClusterIP 10.97.174.187 <none> 9402/TCP 17h
service/cert-manager-webhook ClusterIP 10.104.193.8 <none> 443/TCP 17h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/cert-manager 1/1 1 1 17h
deployment.apps/cert-manager-cainjector 1/1 1 1 17h
deployment.apps/cert-manager-webhook 1/1 1 1 17h
NAME DESIRED CURRENT READY AGE
replicaset.apps/cert-manager-7d75f47cc5 1 1 1 17h
replicaset.apps/cert-manager-cainjector-c778d44d8 1 1 1 17h
replicaset.apps/cert-manager-webhook-55d76f97bb 1 1 1 17h
Let’s Encrypt Issuer設定
下記のようにマニフェストを作成。
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
namespace: default
spec:
# ACME issuer configuration
# `email` - the email address to be associated with the ACME account (make sure it's a valid one)
# `server` - the URL used to access the ACME server’s directory endpoint
# `privateKeySecretRef` - Kubernetes Secret to store the automatically generated ACME account private key
acme:
email: hogehoge@example.net
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
# Use the HTTP-01 challenge provider
- http01:
ingress:
class: traefik
作成したマニフェストを適用。
kubectl apply -f cluster-issuer.yaml
ClusterIssuerが作成されたことを確認。
kubectl get clusterissuers.cert-manager.io
【実行結果例】
NAME READY AGE
letsencrypt-prod True 2d16h
Installing Traefik
TraefikのHelmレポジトリを追加。
helm repo add traefik https://helm.traefik.io/traefik
Helmチャートリポジトリを更新。
helm repo update
HelmでTraefikをインストール。
helm install traefik traefik/traefik -n traefik --create-namespace
インストール確認。
helm ls -n traefik
【実行結果例】
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
traefik traefik 3 2023-12-06 09:19:36.897456 +0900 JST deployed traefik-26.0.0 v2.10.6
リソース状態確認。
kubectl -n traefik get all
【実行結果例】
kubectl -n traefik get all
NAME READY STATUS RESTARTS AGE
pod/traefik-97dbf996d-xk9fr 1/1 Running 0 2d
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/traefik LoadBalancer 10.106.199.85 192.168.0.222 80:31452/TCP,443:30151/TCP 2d16h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/traefik 1/1 1 1 2d16h
NAME DESIRED CURRENT READY AGE
replicaset.apps/traefik-56b7cff4f6 0 0 0 2d16h
replicaset.apps/traefik-66c6596d5f 0 0 0 2d
replicaset.apps/traefik-97dbf996d 1 1 1 2d
Vultr LoadBalancerの確認。
vultr-cli load-balancer list
【実行結果例】
ID d9acf271-70ef-477e-ae97-6a199d92d2b5
DATE CREATED 2023-12-05T07:31:36+00:00
REGION nrt
LABEL a02e3c9dbc9694f3ebf6fb1d9242b267
STATUS active
IPV4 192.168.0.222
IPV6 2001:1XXX:7YYY:0ZZZ:ffff:ffff:ffff:ffff
HAS SSL false
INSTANCES [16e55198-9e20-4cd8-81d7-e4479fb1225d b1b2afdd-0446-4acf-9e4c-9a7d0fa719f2]
HEALTH CHECKS
PROTOCOL PORT PATH CHECK INTERVAL RESPONSE TIMEOUT UNHEALTHY THRESHOLD HEALTHY THRESHOLD
tcp 31452 15 5 5 5
GENERIC INFO
BALANCING ALGORITHM SSL REDIRECT COOKIE NAME PROXY PROTOCOL VPC
roundrobin false false cbf0307c-3d1f-46c5-a1d3-ab2f94783e1d
FORWARDING RULES
RULEID FRONTEND PROTOCOL FRONTEND PORT BACKEND PROTOCOL BACKEND PORT
a82c7c5cfa083700 tcp 80 tcp 31452
94acc21247a5742e tcp 443 tcp 30151
FIREWALL RULES
RULEID PORT SOURCE IP_TYPE
- - -
---------------------------
======================================
TOTAL NEXT PAGE PREV PAGE
1 --- ---
DNS設定
Traefik LoadBalancerの外部IPアドレス(EXTERNAL-IP)を指す192.168.0.222をドメインAレコードに指定する。Vultr DNSの場合は下記のようになる。
vultr-cli dns record list dok8s.net
【実行結果例】
ID TYPE NAME DATA PRIORITY TTL
eeeeeeee-aaaa-4444-11111-99999999999 A www 192.168.0.222 -1 600
HTTP通信設定
まずHTTP通信設定可能か確認、下記SVCへのIngress設定を試す。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dok8s-nginx ClusterIP 10.105.194.159 <none> 80/TCP 5d22h
Ingress設定用マニフェストを作成。
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dok8s-nginx-ingress
namespace: dok8s
annotations:
spec.ingressClassName: traefik
spec:
rules:
- host: www.dok8s.net
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: dok8s-nginx
port:
number: 80
作成したマニフェストを適用。
kubectl apply -f traefik-ingress.yaml
Ingressリソースを確認。
kubectl -n dok8s get ingress dok8s-nginx-ingress
【実行結果例】
NAME CLASS HOSTS ADDRESS PORTS AGE
dok8s-nginx-ingress traefik www.dok8s.net 80 3d7h
HTTP接続確認
curl http://www.dok8s.net/
HTTPS通信設定
Ingress設定用マニフェストを変更。
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dok8s-nginx-ingress
namespace: dok8s
annotations:
spec.ingressClassName: traefik
cert-manager.io/cluster-issuer: letsencrypt-prod
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
rules:
- host: www.dok8s.net
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: dok8s-nginx
port:
number: 80
tls:
- secretName: dok8s-nginx-tls
hosts:
- www.dok8s.net
作成したマニフェストを適用。
kubectl apply -f traefik-ingress.yaml
Ingressリソースを確認。
kubectl -n dok8s get ingress dok8s-nginx-ingress
【実行結果例】
NAME CLASS HOSTS ADDRESS PORTS AGE
dok8s-nginx-ingress traefik www.dok8s.net 80, 443 3d7h
Let’s Encryptサーバー証明書が登録されていることを確認。
kubectl -n dok8s get certificateS dok8s-nginx-tls
READYが”True”になっていれば、サーバー証明書は正常に発行され、使用出来る状態になっている。
NAME READY SECRET AGE
dok8s-nginx-tls True dok8s-nginx-tls 3d8h
証明書が自動更新されることを確認。
kubectl -n dok8s describe certificateS dok8s-nginx-tls|rg -i renewal
Renewal Timeに下記のように日付が設定されていること。
Renewal Time: 2024-02-03T22:50:52Z
HTTPS接続確認
curl https://www.dok8s.net/