1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

はじめての Traefik v2 + cert-manager による https化 奮闘記

Last updated at Posted at 2021-05-13

はじめに

本記事は、既に多くの方が書かれているような「これは、こういうものだ」などの説明は 詳しくないので 省略しており、難しいことは考えず、流れに沿って淡々と作業をする内容になっています。

ゴールは、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から アプリの登録 > 新規登録 を選びます。
image.png

2.アプリケーションの登録の項目を設定した後、登録します。
image.png

  • 名前: try0ut.ml (DNS Zone と同じ名前だと分かり易い)
  • サポートされているアカウントの種類: この組織ディレクトリのみに含まれるアカウント(*** - シングルテナント)
  • リダイレクト URI: http://try0ut.ml (省略でもよい)

3.作成されたサービス プリンシパルのアプリケーション(クライアント)ID (e.g. 430c5a67-157e-4133-89c7-3f974293ea4f) は、後ほど使うのでメモしておきましょう。
image.png

4.サービス プリンシパル証明書とシークレット > 新しいクライアント シークレット を選び、クライアント シークレット を追加します。
image.png

  • 説明: rbac (何でも良い)
  • 有効期限: 推奨: 6 か月 (何でも良い)

有効期限が短い場合は、クラスター内のクライアントシークレットを定期的に入れ替える必要があります。

5.作成されたクライアント シークレットのをコピーします。(画面移動すると非表示になります。)
image.png

6.クライアント シークレットの値をテキスト ファイル(e.g. credentials.env)に保存します。

credentials.env
client-secret=dRRzw-gsleqF6BLxdv_d6C.9s5.qjQT04.

Information:
変数名は client-secret 以外でも構いませんが、後ほど構成するClusterIssuerclientSecretSecretRefを忘れず書き換えるようにしてください。

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) > 追加 > ロールの割り当ての追加 を選びます。
image.png

9.ロールの割り当ての追加にて、作成したサービス プリンシパルDNS ゾーンの共同作成者を割り当てます。
image.png

10.ClusterIssuerを作ります。

issuer.yaml
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 (変数名を変えた場合は変更)
  • 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 を作ります。

whoami-cert.yaml
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.traefikvalues.yamltls を有効にします。

values.yaml
- 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.whoamiIngressRoute を変更します。

whoami-ingress.yaml
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/ にアクセスしてみましょう。
image.png

おわりに

一部のチュートリアルではバージョンが古いなどの理由から、同じ手順で実行できないこともありました。
traefik にも tls のオプションがあるようなので、cert-manager を使わずに簡単にできるかどうかも今後確認していきます。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?