はじめに
本記事は、既に多くの方が書かれているような「これは、こういうものだ」などの説明は 詳しくないので 省略しており、難しいことは考えず、流れに沿って淡々と作業をする内容になっています。
ゴールは、AKSのサービスを Let's Encrypt で https 対応することです。
間違いの指摘や、ここはこうした方がいいよなど、いただけると嬉しいです。
実行環境
本記事では、以下の環境を使用しました。
異なるバージョンでは、同じ結果が得られない場合がありますが、ご了承ください。
Component | Version | |
---|---|---|
OS | macOS | Big Sur 11.3.1 |
TOOL | Kubernetes (AKS) | 1.19.9 |
TOOL | kubectl | 1.19.7 |
TOOL | Azure CLI | 2.21.0 |
TOOL | kubectx, kubens | 0.9.3 |
TOOL | Helm | 3.5.3 |
CHART | traefik | 9.19.0 |
CHART | cert-manager | 1.3.1 |
CHART | whoami | 2.2.0 |
z |
注:
記事中のkc
コマンドは、kubectl
コマンドのエイリアスです。Newbernetes: kubectl the Kubernetes CLI - Cory O'Daniel
を参考にしました。
Let's Encrypt で https 化する
はじめての AKS によるサービス公開に分離しました。
上記で作成したサービスを、無料で使えるSSLサーバー証明書 Let's Encrypt を使ってHTTPS化していきます。
1. cert-managerを導入する
1.cert-manager用の名前空間を作ります。
# 名前空間の作成
$ kc create ns cert-manager
⥤ namespace/cert-manager created
# 名前空間の切り替え
$ kubens cert-manager
⥤ Context "try-traefik-https" modified.
⥤ Active namespace is "cert-manager".
2.helm を使って、cert-manager
をインストールします。
# リポジトリの追加
$ helm repo add jetstack https://charts.jetstack.io
⥤ "jetstack" has been added to your repositories
# CRDs のインストール
$ kc apply -f https://github.com/jetstack/cert-manager/releases/download/v1.3.1/cert-manager.crds.yaml
⥤ customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created
⥤ customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created
⥤ customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created
⥤ customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created
⥤ customresourcedefinition.apiextensions.k8s.io/issuers.cert-manager.io created
⥤ customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io created
# jetstack/cert-manager をインストール
$ helm install cert-manager jetstack/cert-manager
⥤ NAME: cert-manager
⥤ LAST DEPLOYED: Mon May 10 22:33:59 2021
⥤ NAMESPACE: cert-manager
⥤ STATUS: deployed
⥤ REVISION: 1
⥤ TEST SUITE: None
⥤ NOTES:
⥤ cert-manager has been deployed successfully!
⥤ ...
3.正常に動作しているか確認します。
# ポッドの状態
$ kc get po
⥤ NAME READY STATUS RESTARTS AGE
⥤ cert-manager-7998c69865-pct2m 1/1 Running 0 30s
⥤ cert-manager-cainjector-7b744d56fb-spqmg 1/1 Running 0 30s
⥤ cert-manager-webhook-7d6d4c78bc-bg9lv 1/1 Running 0
30s
2. DNS-01 チャレンジ (Azure DNS)
それでは、Let's Encryptの証明書をAzure DNSで発行できるようにしていきます。
GUI操作が嫌いな人は、以下のコマンドで 6. から始められます。
# サービス プリンシパルの作成
$ az ad sp create-for-rbac --name try0ut.ml --years 1
⥤ ...
⥤ {
⥤ "appId": "430c5a67-157e-4133-89c7-3f974293ea4f",
⥤ "displayName": "try0ut.ml",
⥤ "name": "http://try0ut.ml",
⥤ "password": "dRRzw-gsleqF6BLxdv_d6C.9s5.qjQT04.",
⥤ "tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
⥤ }
# 共同作成者 ロールの割り当てを削除
$ az role assignment delete --assignee 430c5a67-157e-4133-89c7-3f974293ea4f --role Contributor
1.Azure Active Directoryから アプリの登録
> 新規登録
を選びます。
- 名前:
try0ut.ml
(DNS Zone と同じ名前だと分かり易い) - サポートされているアカウントの種類:
この組織ディレクトリのみに含まれるアカウント(*** - シングルテナント)
- リダイレクト URI:
http://try0ut.ml
(省略でもよい)
3.作成されたサービス プリンシパルのアプリケーション(クライアント)ID (e.g. 430c5a67-157e-4133-89c7-3f974293ea4f
) は、後ほど使うのでメモしておきましょう。
4.サービス プリンシパルの 証明書とシークレット
> 新しいクライアント シークレット
を選び、クライアント シークレット を追加します。
- 説明:
rbac
(何でも良い) - 有効期限:
推奨: 6 か月
(何でも良い)
有効期限が短い場合は、クラスター内のクライアントシークレットを定期的に入れ替える必要があります。
5.作成されたクライアント シークレットの値をコピーします。(画面移動すると非表示になります。)
6.クライアント シークレットの値をテキスト ファイル(e.g. credentials.env
)に保存します。
client-secret=dRRzw-gsleqF6BLxdv_d6C.9s5.qjQT04.
Information:
変数名はclient-secret
以外でも構いませんが、後ほど構成するClusterIssuerのclientSecretSecretRef
を忘れず書き換えるようにしてください。
7.cert-manager
名前空間にシークレットを入れておきましょう。
# 名前空間の切り替え
$ kubens cert-manager
⥤ Context "try-traefik-https" modified.
⥤ Active namespace is "cert-manager".
# シークレットの作成
$ kc create secret generic azuredns-config --from-env-file ./credentials.env
secret/azuredns-config created
# 機密データの破棄
$ rm -f ./credentials.env
Warning:
--from-literal
を使って直接シークレットを作成してもいいですが、シェルの履歴にパスワードが残ります。
8.Azure DNS ゾーンに移動し、アクセス制御(IAM)
> 追加
> ロールの割り当ての追加
を選びます。
9.ロールの割り当ての追加にて、作成したサービス プリンシパルにDNS ゾーンの共同作成者
を割り当てます。
10.ClusterIssuerを作ります。
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: admin@try0ut.ml
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt
# Enable the HTTP-01/DNS-01 challenge provider
solvers:
- dns01:
azureDNS:
# Service principal clientId (also called appId)
clientID: 430c5a67-157e-4133-89c7-3f974293ea4f
# The following is the secret we created in Kubernetes.
# Issuer will use this to present challenge to Azure DNS.
clientSecretSecretRef:
name: azuredns-config
key: client-secret
# Azure subscription Id
subscriptionID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# Azure AD tenant Id
tenantID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# ResourceGroup name where dns zone is provisioned
resourceGroupName: aks-learning
hostedZoneName: try0ut.ml
environment: AzurePublicCloud
-
email:
admin@try0ut.ml
(Let's Encrypt の有効期限の通知を受け取るメールアドレス) -
clientID:
430c5a67-157e-4133-89c7-3f974293ea4f
(サービスプリンシパルのクライアント ID) -
clientSecretSecretRef
-
name:
azuredns-config
(シークレット名を変えた場合は変更) -
key:
client-secret
(変数名を変えた場合は変更)
-
name:
-
subscriptionID:
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
(サブスクリプションIDを設定) -
tenantID:
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
(Azure AD のテナント IDを設定) -
resourceGroupName:
aks-learning
(DNS ゾーンを配置したリソース グループの名前) -
hostedZoneName:
try0ut.ml
(DNS ゾーンの名前)
$ kc apply -f issuer.yaml
⥤ clusterissuer.cert-manager.io/letsencrypt created
11.Certificate を作ります。
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: whoami-cert
namespace: whoami
spec:
commonName: whoami.try0ut.ml
secretName: whoami-cert
dnsNames:
- whoami.try0ut.ml
issuerRef:
name: letsencrypt
kind: ClusterIssuer
$ kc apply -f whoami-cert.yaml
⥤ certificate.cert-manager.io/whoami-cert created
12.traefik の values.yaml
で tls を有効にします。
- additionalArguments: []
- # - "--providers.kubernetesingress.ingressclass=traefik-internal"
+ additionalArguments:
+ - "--entrypoints.websecure.http.tls"
# 名前空間の切り替え
$ kubens traefik
⥤ Context "try-traefik-https" modified.
⥤ Active namespace is "traefik".
# 新しい設定値でアップグレード
$ helm upgrade traefik traefik/traefik -f values.yaml
⥤ Release "traefik" has been upgraded. Happy Helming!
⥤ NAME: traefik
⥤ LAST DEPLOYED: Mon May 10 22:46:11 2021
⥤ NAMESPACE: traefik
⥤ STATUS: deployed
⥤ REVISION: 2
⥤ TEST SUITE: None
13.whoami の IngressRoute を変更します。
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace whoami
spec:
entryPoints:
- websecure
routes:
- match: Host(`whoami.try0ut.ml`)
kind: Rule
services:
- name: whoami
port: 80
+ tls:
+ secretName: whoami-cert
$ kc apply -f whoami-ingress.yaml
⥤ ingressroute.traefik.containo.us/whoami configured
14.Webブラウザーで、https://whoami.try0ut.ml/ にアクセスしてみましょう。
おわりに
一部のチュートリアルではバージョンが古いなどの理由から、同じ手順で実行できないこともありました。
traefik
にも tls
のオプションがあるようなので、cert-manager
を使わずに簡単にできるかどうかも今後確認していきます。