Cert-Managerは、証明書管理に使用されるコントローラーです。 Cert-Managerは、Let’s Encrypt、HashiCorp Vault、Venafi、単純な署名キーペア、自己署名などのさまざまな発行者から証明書を発行するのに役立ちます。 Cert-Managerは証明書を検証し、証明書が最新であることを確認し、有効期限が切れる前に更新します。 Cert-Managerは、以下に示すようにいくつかのコンポーネントで構成されています。
- 発行者 :IssuersとClusterIssuersは、署名付き証明書を生成できる認証局(CA)を表すKubernetesのオブジェクトです。
- 証明書 :証明書は、IssuerまたはClusterIssuerを参照する名前空間付きのリソースであり、更新されて最新の状態に保たれます。
- CertificateRequest :CertificateRequestは、発行者またはクラスタ発行者に証明書をリクエストするために使用される名前空間付きリソースです。
- ACME注文 :注文は、ACME発行者を参照する新しいCertificateRequestリソースが作成されると作成される証明書リクエストを表します
- ACMEの課題 :注文リソースが作成されると、ACMEサーバーで承認されている各DNS名のチャレンジリソースが注文管理者によって作成されます。
- Webhook :メインのCert-Managerポッドとともに別のポッドとしてデプロイされ、ValidatingAdmissionWebhook、MutatingAdmissionWebhook、CustomResourceConversionWebhookの3つの機能があります。
- CA Injecto r:Webhookの検証、Webhookの変更、およびWebhookの変換のための証明書を構成するのに役立ちます。
この記事では、Let'sEncrypt発行者を使用してCert-Managerをセットアップします。 TLS証明書を使用してサンプルアプリケーションを保護し、Ingressを使用してアプリケーションにアクセスするためにホスト名にHTTPSを含めます。これを行うために、Ingressにアノテーションを追加して、証明書リソースが私たちに代わって作成されるようにします。
Cert-Managerの詳細については、こちらの公式ドキュメントをご覧ください。この記事の焦点は、Helmを使用したCert-Managerのセットアップにあり、Cert-Managerに関連する概念に精通していることを前提としています。
- AWSアカウント(アカウントがない場合は作成します)。
- Kubernetes Cluster(Kopsを使用してKubernetes Clusterを作成する方法と詳細については、ここをクリックしてください。)
- K8SクラスターのNginxIngressController(Nginx Ingress Controllerのセットアップ方法については、「IngressControllerとは何ですか。Helmを使用してAWSのKubernetesClusterにNginxIngressControllerをデプロイする方法」を検索してください)
- Helm v3.5.3(Ubuntu ServerにHelmをインストールする方法については、ここをクリックしてください)
- S3バケット(AWSでS3バケットを作成する方法については、ここをクリックしてください)。
- ドメイン名(AWSにドメインを登録する方法については、ここをクリックしてください)。
- 管理者権限を持つIAMロール(AWSでIAMロールを作成する方法については、ここをクリックしてください)。
何をしますか?
- クラスター内の入力コントローラーを確認する
- 証明書マネージャーを設定する
- サンプルアプリケーションのオブジェクト定義ファイルを作成する
- ステージングと本番のセットアップ発行者を暗号化しましょう
- サンプルアプリケーションをデプロイする
- TLSを使用して入力オブジェクトをデプロイする
続行する前に、クラスターでNginxIngressControllerが実行されているかどうかを確認してください。
kubectl get pods
kubectl get svc
Note: I have used Helm binary present at my current location, hence you can see ./helm in screenshots.
Helm v3.5.3を使用して次のコマンドを実行すると、Cert-ManagerのHelmチャートがインストールされます。
kubectl create namespace cert-manager
helm repo add jetstack https://charts.jetstack.io
helm repo update helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.2.0 --set installCRDs=true
上のスクリーンショットでは、Cert-Managerのヘルムチャートがインストールされていることがわかります。
Cert-Managerの一部として作成されたポッドを確認してください。
kubectl get pods -A
「cert-manager」名前空間に3つの新しいポッドが表示されます。
アプリケーション1用に1-nginx-main-app.yamlを作成します
Githubリンク:ここをクリックして、Githubリポジトリからファイルをコピーします。
apiVersion: apps/v1 kind: Deployment metadata: labels: run: nginx name: nginx-deploy-main spec: replicas: 1 selector: matchLabels: run: nginx-main template: metadata: labels: run: nginx-main spec: containers: - image: nginx name: nginx --- apiVersion: v1 kind: Service metadata: name: nginx-deploy-main spec: type: ClusterIP ports: - port: 80 targetPort: 80 selector: run: nginx-main
アプリケーション2用に2-nginx-green-app.yamlを作成します。
Githubリンク:ここをクリックして、Githubリポジトリからファイルをコピーします。
apiVersion: apps/v1 kind: Deployment metadata: labels: run: nginx name: nginx-deploy-green spec: replicas: 1 selector: matchLabels: run: nginx-green template: metadata: labels: run: nginx-green spec: volumes: - name: webdata emptyDir: {} initContainers: - name: web-content image: busybox volumeMounts: - name: webdata mountPath: "/webdata" command: ["/bin/sh", "-c", 'echo "<h1>I am <font color=green>GREEN</font></h1>" > /webdata/index.html'] containers: - image: nginx name: nginx volumeMounts: - name: webdata mountPath: "/usr/share/nginx/html" --- --- apiVersion: v1 kind: Service metadata: name: nginx-deploy-green spec: type: ClusterIP ports: - port: 80 targetPort: 80 selector: run: nginx-green
アプリケーション3用に3-nginx-blue-app.yamlを作成します
Githubリンク:ここをクリックして、Githubリポジトリからファイルをコピーします。
apiVersion: apps/v1 kind: Deployment metadata: labels: run: nginx name: nginx-deploy-blue spec: replicas: 1 selector: matchLabels: run: nginx-blue template: metadata: labels: run: nginx-blue spec: volumes: - name: webdata emptyDir: {} initContainers: - name: web-content image: busybox volumeMounts: - name: webdata mountPath: "/webdata" command: ["/bin/sh", "-c", 'echo "<h1>I am <font color=blue>BLUE</font></h1>" > /webdata/index.html'] containers: - image: nginx name: nginx volumeMounts: - name: webdata mountPath: "/usr/share/nginx/html" --- apiVersion: v1 kind: Service metadata: name: nginx-deploy-blue spec: type: ClusterIP ports: - port: 80 targetPort: 80 selector: run: nginx-blue
StagingIssuerでパスベースのIngressルールを作成するための4-tls-ingress.yamlを作成します。
Githubリンク:ここをクリックして、Githubリポジトリからファイルをコピーします。
apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/rewrite-target: / cert-manager.io/cluster-issuer: letsencrypt-staging name: ingress-resource-3 spec: tls: - hosts: - kops.devopslee.com secretName: sample-kubernetes-tls rules: - host: kops.devopslee.com http: paths: - path: / backend: serviceName: nginx-deploy-main servicePort: 80 - path: /blue backend: serviceName: nginx-deploy-blue servicePort: 80 - path: /green backend: serviceName: nginx-deploy-green servicePort: 80
Production Issuerを使用してパスベースのIngressルールを作成するために、5-tls-ingress-prod-issuer.yamlを作成します。
Githubリンク:ここをクリックして、Githubリポジトリからファイルをコピーします。
apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/rewrite-target: / cert-manager.io/cluster-issuer: letsencrypt-production name: ingress-resource-3 spec: tls: - hosts: - kops.devopslee.com secretName: sample-kubernetes-tls rules: - host: kops.devopslee.com http: paths: - path: / backend: serviceName: nginx-deploy-main servicePort: 80 - path: /blue backend: serviceName: nginx-deploy-blue servicePort: 80 - path: /green backend: serviceName: nginx-deploy-green servicePort: 80
Let's EncryptStagingIssuerのstaging_issuer.yamlを作成します
Githubリンク:ここをクリックして、Githubリポジトリからファイルをコピーします。
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-staging spec: acme: # Email address used for ACME registration email: your-email-id-here server: https://acme-staging-v02.api.letsencrypt.org/directory privateKeySecretRef: # Name of a secret used to store the ACME account private key name: letsencrypt-staging-private-key # Add a single challenge solver, HTTP01 using nginx solvers: - http01: ingress: class: nginx
Let's Encrypt ProductionIssuerのproduction_issuer.yamlを作成します
Githubリンク:ここをクリックして、Githubリポジトリからファイルをコピーします。
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-production spec: acme: # Email address used for ACME registration email: your-email-id-here server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: # Name of a secret used to store the ACME account private key name: letsencrypt-production-private-key # Add a single challenge solver, HTTP01 using nginx solvers: - http01: ingress: class: nginx
これらのファイルはすべて、Githubリポジトリのこちらにあります。
StagingとProductionClusterIssuerの両方をインストールします。
ステージング :
ステージングには「サーバー:https://acme-staging-v02.api.letsencrypt.org/directory」があります
kubectl logs cert-manager-56f5c44b5d-jn46m -n cert-manager -f
kubectl apply -f cluster-issuer/staging_issuer.yaml
これにより、「letsencrypt-staging-private-key」という名前のシークレットが作成されます
kubectl get secret letsencrypt-staging-private-key -n cert-manager -o json
生産 :
本番環境には「サーバー:https://acme-v02.api.letsencrypt.org/directory」
がありますkubectl logs cert-manager-56f5c44b5d-jn46m -n cert-manager -f
kubectl apply -f cluster-issuer/production_issuer.yaml
これにより、「letsencrypt-production-private-key」という名前のシークレットが作成されます
kubectl get secret letsencrypt-production-private-key -n cert-manager -o json
3つのサンプルアプリケーションをデプロイしましょう。
kubectl apply -f sample-app/1-nginx-main-app.yaml
kubectl apply -f sample-app/2-nginx-green-app.yaml
kubectl apply -f sample-app/3-nginx-blue-app.yaml
Check the deployments, pods, and services created by the above commands.
kubectl get deployments
kubectl get pods kubectl
get service
まず、ステージング発行者を使用してIngressをデプロイしましょう。
kubectl apply -f sample-app/4-tls-ingress.yaml
kubectl get ingress
kubectl describe ingress ingress-resource-3
Ingressリソースが作成されると、バックグラウンドで何が起こったかを確認して、IngressのTLSセクションの証明書を発行できます。
kubectl get certificate -A
kubectl get certificaterequests.cert-manager.io -A
kubectl get orders.acme.cert-manager.io -A
kubectl get challenges.acme.cert-manager.io -A
kubectl get certificate -o json | grep secretName
kubectl get secret sample-kubernetes-tls -o yaml
これでアプリケーションにHTTPS経由でアクセスできるようになりましたが、Let's Encrypt発行者のステージング環境を使用しているため、「このサイトへの接続は安全ではありません」という警告が表示されます。
本番発行者を使用してIngressをデプロイします。
それでは、ステージングを使用してIngressを削除し、本番発行者を指す新しいIngressを作成しましょう。
kubectl delete -f sample-app/4-tls-ingress.yaml
kubectl apply -f sample-app/5-tls-ingress-prod-issuer.yaml
kubectl get ingress
kubectl describe ingress ingress-resource-3
今回、アプリケーションにアクセスしようとしても、「このサイトへの接続は安全ではありません」という警告は表示されません。
この記事では、KubernetesクラスターにCert-Managerを設定する手順について説明しました。サンプルアプリケーションをデプロイし、パスに基づいて入力を介してトラフィックをルーティングし、Let'sEncryptクラスター発行者によって発行された証明書を使用してHTTPSとの接続を保護しました。最初にLet'sEncryptステージング環境を使用して証明書を発行し、次にLet'sEncryptの本番環境を使用しました