DigitalOcean KubernetesでCert-Managerを使用してNginx Ingressをセットアップする方法

前書き

KubernetesIngressesを使用すると、Kubernetesクラスターの外部からクラスター内のサービスにトラフィックを柔軟にルーティングできます。 これは、HTTPおよびHTTPSトラフィックをKubernetesサービスにルーティングするためのルールを定義するIngressResourcesと、トラフィックを負荷分散して適切なバックエンドサービスにルーティングすることでルールを実装するIngressControllersを使用して実現されます。 人気のある入力コントローラーには、NginxContourHAProxy、およびTraefikが含まれます。 Ingressは、それぞれが専用のロードバランサーを使用する複数のLoadBalancerサービスをセットアップするより効率的で柔軟な代替手段を提供します。

このガイドでは、Kubernetesで管理されているNginx Ingress Controllerを設定し、トラフィックをいくつかのダミーバックエンドサービスにルーティングするための入力リソースをいくつか作成します。 Ingressを設定したら、cert-managerをクラスターにインストールして、IngressへのHTTPトラフィックを暗号化するためのTLS証明書を管理およびプロビジョニングします。

前提条件

このガイドを始める前に、次のものを用意しておく必要があります。

  • role-based access control(RBAC)が有効になっているKubernetes1.10 +クラスター

  • ローカルマシンにインストールされ、クラスターに接続するように構成されたkubectlコマンドラインツール。 kubectlin the official documentationのインストールについて詳しく読むことができます。

  • Ingressが使用するDigitalOceanロードバランサーを指すことができるドメイン名とDNS Aレコード。 DigitalOceanを使用してドメインのDNSレコードを管理している場合は、How to Manage DNS Recordsを参照してAレコードを作成する方法を確認してください。

  • How To Install Software on Kubernetes Clusters with the Helm Package Managerで詳しく説明されているように、ローカルマシンにインストールされたHelmパッケージマネージャーとクラスターにインストールされたTiller。 Helm v2.12.1以降を使用していることを確認してください。さもないと、cert-manager Helmチャートのインストールで問題が発生する可能性があります。 インストールしたHelmのバージョンを確認するには、ローカルマシンでhelm versionを実行します。

  • ローカルマシンにインストールされているwgetコマンドラインユーティリティ。 オペレーティングシステムに組み込まれているパッケージマネージャーを使用して、wgetをインストールできます。

これらのコンポーネントをセットアップしたら、このガイドから始める準備ができました。

[[step-1 -—- setting-up-dummy-backend-services]] ==ステップ1—ダミーバックエンドサービスの設定

Ingress Controllerを展開する前に、Ingressを使用して外部トラフィックをルーティングする2つのダミーエコーサービスを作成して展開します。 echo Servicesは、hashicorp/http-echo Webサーバーコンテナを実行します。このコンテナは、Webサーバーの起動時に渡されたテキスト文字列を含むページを返します。 http-echoの詳細については、そのGitHub Repoを参照してください。また、Kubernetesサービスの詳細については、Kubernetesの公式ドキュメントからServicesを参照してください。

ローカルマシンで、nanoまたはお気に入りのエディターを使用してecho1.yamlというファイルを作成および編集します。

nano echo1.yaml

次のサービスおよび展開マニフェストに貼り付けます。

echo1.yaml

apiVersion: v1
kind: Service
metadata:
  name: echo1
spec:
  ports:
  - port: 80
    targetPort: 5678
  selector:
    app: echo1
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo1
spec:
  selector:
    matchLabels:
      app: echo1
  replicas: 2
  template:
    metadata:
      labels:
        app: echo1
    spec:
      containers:
      - name: echo1
        image: hashicorp/http-echo
        args:
        - "-text=echo1"
        ports:
        - containerPort: 5678

このファイルでは、app: echo1ラベルセレクターを使用してトラフィックをポッドにルーティングするecho1というサービスを定義します。 ポート80でTCPトラフィックを受け入れ、ポート5678http-echoのデフォルトポートにルーティングします。

次に、app: echo1Label Selectorでポッドを管理するecho1とも呼ばれるデプロイメントを定義します。 デプロイメントには2つのポッドレプリカが必要であり、ポッドはhashicorp/http-echoイメージを実行するecho1というコンテナーを開始する必要があることを指定します。 textパラメータを渡してecho1に設定し、http-echo Webサーバーがecho1を返すようにします。 最後に、ポッドコンテナのポート5678を開きます。

ダミーのサービスと展開マニフェストに満足したら、ファイルを保存して閉じます。

次に、-fフラグを指定してkubectl createを使用し、保存したファイルをパラメーターとして指定して、Kubernetesリソースを作成します。

kubectl create -f echo1.yaml

次のような出力が表示されるはずです。

Outputservice/echo1 created
deployment.apps/echo1 created

サービスが公開されている内部IPであるClusterIPがあることを確認して、サービスが正しく開始されたことを確認します。

kubectl get svc echo1

次のような出力が表示されるはずです。

OutputNAME      TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
echo1     ClusterIP   10.245.222.129           80/TCP    60s

これは、echo1サービスがポート8010.245.222.129で内部的に利用可能になったことを示しています。 選択したポッドのcontainerPort5678にトラフィックを転送します。

echo1サービスが稼働しているので、echo2サービスに対してこのプロセスを繰り返します。

echo2.yamlというファイルを作成して開きます。

echo2.yaml

apiVersion: v1
kind: Service
metadata:
  name: echo2
spec:
  ports:
  - port: 80
    targetPort: 5678
  selector:
    app: echo2
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo2
spec:
  selector:
    matchLabels:
      app: echo2
  replicas: 1
  template:
    metadata:
      labels:
        app: echo2
    spec:
      containers:
      - name: echo2
        image: hashicorp/http-echo
        args:
        - "-text=echo2"
        ports:
        - containerPort: 5678

ここでは、基本的に上記と同じService and Deploymentマニフェストを使用しますが、Service and Deploymentecho2に名前を付けてラベルを付け直します。 さらに、いくつかの多様性を提供するために、1つのPodレプリカのみを作成します。 Webサーバーがテキストecho2を返すように、textパラメーターをecho2に設定していることを確認します。

ファイルを保存して閉じ、kubectlを使用してKubernetesリソースを作成します。

kubectl create -f echo2.yaml

次のような出力が表示されるはずです。

Outputservice/echo2 created
deployment.apps/echo2 created

もう一度、サービスが稼働していることを確認します。

kubectl get svc

ClusterIPが割り当てられたecho1サービスとecho2サービスの両方が表示されます。

OutputNAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
echo1        ClusterIP   10.245.222.129           80/TCP    6m6s
echo2        ClusterIP   10.245.128.224           80/TCP    6m3s
kubernetes   ClusterIP   10.245.0.1               443/TCP   4d21h

ダミーエコーWebサービスが稼働しているので、Nginx Ingress Controllerのロールアウトに進むことができます。

[[step-2 -—- setting-up-the-kubernetes-nginx-ingress-controller]] ==ステップ2— Kubernetes Nginx IngressControllerのセットアップ

このステップでは、Kubernetesで管理されているNginx Ingress Controllerv0.24.1をロールアウトします。 severalのNginx IngressControllerがあることに注意してください。 Kubernetesコミュニティは、このガイドとNginxIncで使用されているコミュニティを維持しています。 kubernetes-ingressを維持します。 このチュートリアルの手順は、公式のKubernetes Nginx Ingress ControllerInstallation Guideの手順に基づいています。

Nginx Ingress Controllerは、Nginx Webサーバーを実行し、新規および更新されたIngress ResourceオブジェクトのKubernetesコントロールプレーンを監視するポッドで構成されます。 イングレスリソースは、基本的にバックエンドサービスのトラフィックルーティングルールのリストです。 たとえば、Ingressルールは、パス/web1に到着するHTTPトラフィックをweb1バックエンドWebサーバーに送信するように指定できます。 Ingress Resourcesを使用して、ホストベースのルーティングを実行することもできます。たとえば、web1.your_domain.comにヒットしたリクエストをバックエンドのKubernetesサービスweb1にルーティングします。

この場合、Ingress ControllerをDigitalOcean Kubernetesクラスターに展開しているため、Controllerは、すべての外部トラフィックが送信されるDigitalOceanロードバランサーをスピンアップするLoadBalancerサービスを作成します。 このロードバランサーは、外部トラフィックをNginxを実行しているIngress Controller Podにルーティングし、次にIngin Controller Podが適切なバックエンドサービスにトラフィックを転送します。

まず、Nginx Ingress Controllerに必要なKubernetesリソースを作成します。 これらは、コントローラーの構成を含むConfigMap、Kubernetes APIへのコントローラーアクセスを許可するロールベースのアクセス制御(RBAC)ロール、およびNginx Ingressコントローラーイメージのv0.24.1を使用する実際のIngressコントローラーデプロイメントで構成されます。 これらの必要なリソースの完全なリストを確認するには、Kubernetes Nginx Ingress ControllerのGitHubリポジトリのmanifestを参照してください。

これらの必須リソースを作成するには、kubectl apply-fフラグを使用して、GitHubでホストされているマニフェストファイルを指定します。

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/mandatory.yaml

ここではcreateの代わりにapplyを使用しているため、将来、Ingress Controllerオブジェクトを完全に上書きするのではなく、applyの変更を段階的に変更できます。 applyの詳細については、Kubernetesの公式ドキュメントからManaging Resourcesを参照してください。

次のような出力が表示されるはずです。

Outputnamespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.extensions/nginx-ingress-controller created

この出力は、mandatory.yamlマニフェストから作成されたすべてのIngressControllerオブジェクトの便利な要約としても機能します。

次に、Ingress Controller LoadBalancerサービスを作成します。このサービスは、前のコマンドで展開したIngress Controller PodにHTTPおよびHTTPSトラフィックの負荷を分散してルーティングするDigitalOceanロードバランサーを作成します。

LoadBalancerサービスを作成するには、サービス定義を含むマニフェストファイルをもう一度kubectl applyします。

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/provider/cloud-generic.yaml

次のような出力が表示されるはずです。

Outputservice/ingress-nginx created

ここで、kubectlを使用してサービスの詳細をフェッチすることにより、DigitalOceanロードバランサーが正常に作成されたことを確認します。

kubectl get svc --namespace=ingress-nginx

DigitalOceanロードバランサーのIPアドレスに対応する外部IPアドレスが表示されます。

OutputNAME            TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                      AGE
ingress-nginx   LoadBalancer   10.245.247.67   203.0.113.0   80:32486/TCP,443:32096/TCP   20h

後の手順で必要になるので、ロードバランサーの外部IPアドレスを書き留めます。

[.note]#Note:デフォルトでは、Nginx Ingress LoadBalancerサービスのservice.spec.externalTrafficPolicyは値Localに設定されており、すべてのロードバランサートラフィックをNginx IngressPodを実行しているノードにルーティングします。 他のノードは、入力トラフィックがそれらにルーティングされないように、ロードバランサーのヘルスチェックに意図的に失敗します。 外部トラフィックポリシーはこのチュートリアルの範囲を超えていますが、詳細については、公式のKubernetesドキュメントのA Deep Dive into Kubernetes External Traffic PoliciesSource IP for Services with Type=LoadBalancerを参照してください。

このロードバランサーは、HTTPおよびHTTPSポート80および443でトラフィックを受信し、それを入力コントローラーポッドに転送します。 入力コントローラーは、トラフィックを適切なバックエンドサービスにルーティングします。

これで、この外部ロードバランサーでDNSレコードをポイントし、トラフィックルーティングルールを実装するためのIngressリソースを作成できます。

[[step-3 -—- creating-the-ingress-resource]] ==ステップ3—入力リソースの作成

まず、最小限のイングレスリソースを作成して、特定のサブドメインに向けられたトラフィックを対応するバックエンドサービスにルーティングします。

このガイドでは、テストドメインexample.comを使用します。 これを所有するドメイン名で置き換える必要があります。

最初に、echo1.example.comに向けられたトラフィックをecho1バックエンドサービスにルーティングし、echo2.example.comに向けられたトラフィックをecho2バックエンドサービスにルーティングする簡単なルールを作成します。

お気に入りのエディターでecho_ingress.yamlというファイルを開くことから始めます。

nano echo_ingress.yaml

次のイングレス定義に貼り付けます。

echo_ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: echo-ingress
spec:
  rules:
  - host: echo1.example.com
    http:
      paths:
      - backend:
          serviceName: echo1
          servicePort: 80
  - host: echo2.example.com
    http:
      paths:
      - backend:
          serviceName: echo2
          servicePort: 80

Ingressルールの編集が終了したら、ファイルを保存して閉じます。

ここでは、echo-ingressという入力リソースを作成し、ホストヘッダーに基づいてトラフィックをルーティングすることを指定しました。 HTTP要求のHostヘッダーは、ターゲットサーバーのドメイン名を指定します。 ホストリクエストヘッダーの詳細については、Mozilla Developer Networkdefinition pageを参照してください。 ホストecho1.example.comを使用した要求は、ステップ1で設定したecho1バックエンドに送信され、ホストecho2.example.comを使用した要求は、echo2バックエンドに送信されます。

これで、kubectlを使用してIngressを作成できます。

kubectl apply -f echo_ingress.yaml

Ingressの作成を確認する次の出力が表示されます。

Outputingress.extensions/echo-ingress created

Ingressをテストするには、DNS管理サービスに移動し、DigitalOceanロードバランサーの外部IPを指すecho1.example.comecho2.example.comのAレコードを作成します。 ロードバランサーの外部IPは、前の手順で取得したingress-nginxサービスの外部IPアドレスです。 DigitalOceanを使用してドメインのDNSレコードを管理している場合は、How to Manage DNS Recordsを参照してAレコードを作成する方法を確認してください。

必要なecho1.example.comおよびecho2.example.com DNSレコードを作成したら、curlコマンドラインユーティリティを使用して、作成したIngressControllerおよびResourceをテストできます。

ローカルマシンから、curlecho1サービス:

curl echo1.example.com

echo1サービスから次の応答が返されます。

Outputecho1

これにより、echo1.example.comへのリクエストがNginx入力を介してecho1バックエンドサービスに正しくルーティングされていることが確認されます。

ここで、echo2サービスに対して同じテストを実行します。

curl echo2.example.com

echo2サービスから次の応答が返されます。

Outputecho2

これにより、echo2.example.comへのリクエストがNginx入力を介してecho2バックエンドサービスに正しくルーティングされていることが確認されます。

この時点で、仮想ホストベースのルーティングを実行するための基本的なNginx Ingressのセットアップが正常に完了しました。 次のステップでは、Helmを使用してcert-managerをインストールし、IngressのTLS証明書をプロビジョニングして、より安全なHTTPSプロトコルを有効にします。

[[step-4 -—- installing-and-configuring-cert-manager]] ==ステップ4—Cert-Managerのインストールと構成

この手順では、Helmを使用してcert-managerをクラスターにインストールします。 cert-managerは、Let’s Encryptおよびその他の認証局からTLS証明書をプロビジョニングし、それらのライフサイクルを管理するKubernetesサービスです。 証明書は、Ingressリソースにcertmanager.k8s.io/issuer注釈を付け、tlsセクションをIngress仕様に追加し、1つ以上のIssuersを構成して、優先する認証局を指定することにより、要求および構成できます。 発行者オブジェクトの詳細については、Issuersに関する公式のcert-managerドキュメントを参照してください。

[.note]#Note: cert-managerをインストールする前に、Helmv2.12.1以降を使用していることを確認してください。 インストールしたHelmのバージョンを確認するには、ローカルマシンでhelm versionを実行します。

Helmを使用してcert-managerをクラスターにインストールする前に、cert-managerCustom Resource Definitions(CRD)を作成する必要があります。 これらは、cert-managerGitHub repositoryから直接「適用」して作成します。

kubectl apply \
    -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml

次のような出力が表示されるはずです。

Outputcustomresourcedefinition.apiextensions.k8s.io/certificates.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/issuers.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/clusterissuers.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/orders.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/challenges.certmanager.k8s.io created

次に、kube-system名前空間にラベルを追加します。ここにcert-managerをインストールして、webhookを使用した高度なリソース検証を有効にします。

kubectl label namespace kube-system certmanager.k8s.io/disable-validation="true"

次に、Jetstack Helm repositoryをHelmに追加します。 このリポジトリには、cert-managerHelm chartが含まれています。

helm repo add jetstack https://charts.jetstack.io

最後に、チャートをkube-system名前空間にインストールできます。

helm install --name cert-manager --namespace kube-system jetstack/cert-manager --version v0.8.0

次のような出力が表示されるはずです。

Output. . .
NOTES:
cert-manager has been deployed successfully!

In order to begin issuing certificates, you will need to set up a ClusterIssuer
or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).

More information on the different types of issuers and how to configure them
can be found in our documentation:

https://cert-manager.readthedocs.io/en/latest/reference/issuers.html

For information on how to configure cert-manager to automatically provision
Certificates for Ingress resources, take a look at the `ingress-shim`
documentation:

https://cert-manager.readthedocs.io/en/latest/reference/ingress-shim.html

これは、cert-managerのインストールが成功したことを示しています。

Ingressホストの証明書の発行を開始する前に、署名されたx509証明書を取得できる認証局を指定する発行者を作成する必要があります。 このガイドでは、無料のTLS証明書を提供し、証明書構成をテストするためのステージングサーバーと検証可能なTLS証明書を展開するための運用サーバーの両方を提供するLet's Encrypt認証局を使用します。

テスト発行者を作成して、証明書のプロビジョニングメカニズムが正しく機能していることを確認します。 お気に入りのテキストエディタでstaging_issuer.yamlという名前のファイルを開きます。

nano staging_issuer.yaml

次のClusterIssuerマニフェストに貼り付けます。

staging_issuer.yaml

apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
 name: letsencrypt-staging
spec:
 acme:
   # The ACME server URL
   server: https://acme-staging-v02.api.letsencrypt.org/directory
   # Email address used for ACME registration
   email: your_email_address_here
   # Name of a secret used to store the ACME account private key
   privateKeySecretRef:
     name: letsencrypt-staging
   # Enable the HTTP-01 challenge provider
   http01: {}

ここでは、letsencrypt-stagingという名前のClusterIssuerオブジェクトを作成し、Let’sEncryptステージングサーバーを使用することを指定します。 後で実稼働サーバーを使用して証明書を公開しますが、実稼働サーバーはそれに対して行われたリクエストのレートを制限する場合があるため、テスト目的ではステージングURLを使用するのが最善です。

次に、証明書を登録するためのメールアドレスを指定し、ACMEアカウントの秘密鍵を保存するためにletsencrypt-stagingと呼ばれるKubernetesSecretを作成します。 また、HTTP-01チャレンジメカニズムを有効にします。 これらのパラメーターの詳細については、Issuersに関する公式のcert-managerドキュメントを参照してください。

kubectlを使用してClusterIssuerをロールアウトします。

kubectl create -f staging_issuer.yaml

次のような出力が表示されるはずです。

Outputclusterissuer.certmanager.k8s.io/letsencrypt-staging created

Let's Encryptステージング発行者を作成したので、上記で作成したIngressリソースを変更し、echo1.example.comおよびecho2.example.comパスのTLS暗号化を有効にする準備ができました。

お気に入りのエディターでecho_ingress.yamlをもう一度開きます。

nano echo_ingress.yaml

Ingress Resourceマニフェストに次を追加します。

echo_ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: echo-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    certmanager.k8s.io/cluster-issuer: letsencrypt-staging
spec:
  tls:
  - hosts:
    - echo1.example.com
    - echo2.example.com
    secretName: letsencrypt-staging
  rules:
  - host: echo1.example.com
    http:
      paths:
      - backend:
          serviceName: echo1
          servicePort: 80
  - host: echo2.example.com
    http:
      paths:
      - backend:
          serviceName: echo2
          servicePort: 80

ここでは、ingress.classを指定するための注釈をいくつか追加します。これにより、入力ルールの実装に使用する入力コントローラーが決まります。 さらに、cluster-issuerletsencrypt-stagingと定義します。これは、作成したばかりの証明書発行者です。

最後に、tlsブロックを追加して、証明書を取得するホストを指定し、secretNameを指定します。 このシークレットには、TLS秘密鍵と発行された証明書が含まれます。

変更が完了したら、ファイルを保存して閉じます。

次に、kubectl applyを使用して既存の入力リソースを更新します。

kubectl apply -f echo_ingress.yaml

次のような出力が表示されるはずです。

Outputingress.extensions/echo-ingress configured

kubectl describeを使用して、適用したばかりのIngressの変更の状態を追跡できます。

kubectl describe ingress
OutputEvents:
  Type    Reason             Age               From                      Message
  ----    ------             ----              ----                      -------
  Normal  CREATE             14m               nginx-ingress-controller  Ingress default/echo-ingress
  Normal  UPDATE             1m (x2 over 13m)  nginx-ingress-controller  Ingress default/echo-ingress
  Normal  CreateCertificate  1m                cert-manager              Successfully created Certificate "letsencrypt-staging"

証明書が正常に作成されたら、証明書に対して追加のdescribeを実行して、証明書が正常に作成されたことをさらに確認できます。

kubectl describe certificate

Eventsセクションに次の出力が表示されます。

OutputEvents:
  Type    Reason         Age   From          Message
  ----    ------         ----  ----          -------
  Normal  Generated      63s   cert-manager  Generated new private key
  Normal  OrderCreated   63s   cert-manager  Created Order resource "letsencrypt-staging-147606226"
  Normal  OrderComplete  19s   cert-manager  Order "letsencrypt-staging-147606226" completed successfully
  Normal  CertIssued     18s   cert-manager  Certificate issued successfully

これにより、TLS証明書が正常に発行され、HTTPS暗号化が構成された2つのドメインに対してアクティブになったことを確認できます。

これで、バックエンドechoサーバーにリクエストを送信して、HTTPSが正しく機能していることをテストする準備が整いました。

次のwgetコマンドを実行して、リクエストをecho1.example.comに送信し、応答ヘッダーをSTDOUTに出力します。

wget --save-headers -O- echo1.example.com

次のような出力が表示されるはずです。

OutputURL transformed to HTTPS due to an HSTS policy
--2018-12-11 14:38:24--  https://echo1.example.com/
Resolving echo1.example.com (echo1.example.com)... 203.0.113.0
Connecting to echo1.example.com (echo1.example.net)|203.0.113.0|:443... connected.
ERROR: cannot verify echo1.example.com's certificate, issued by ‘CN=Fake LE Intermediate X1’:
  Unable to locally verify the issuer's authority.
To connect to echo1.example.com insecurely, use `--no-check-certificate'.

これは、HTTPSが正常に有効化されたことを示しますが、Let’s Encryptステージングサーバーによって発行された偽の一時証明書であるため、証明書を検証できません。

この一時的な偽の証明書を使用してすべてが機能することをテストしたので、2つのホストecho1.example.comecho2.example.comの本番証明書を展開できます。

[[step-5 --- rolling-out-production-issuer]] ==ステップ5— ProductionIssuerのロールアウト

このステップでは、ステージング証明書のプロビジョニングに使用される手順を変更し、イングレスホスト用の有効で検証可能な本番証明書を生成します。

まず、ClusterIssuerの運用証明書を作成します。

お気に入りのエディターでprod_issuer.yamlというファイルを開きます。

nano prod_issuer.yaml

次のマニフェストに貼り付けます。

prod_issuer.yaml

apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    # The ACME server URL
    server: https://acme-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: your_email_address_here
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-prod
    # Enable the HTTP-01 challenge provider
    http01: {}

異なるACMEサーバーのURLとletsencrypt-prodの秘密鍵名に注意してください。

編集が完了したら、ファイルを保存して閉じます。

ここで、kubectlを使用してこの発行者をロールアウトします。

kubectl create -f prod_issuer.yaml

次のような出力が表示されるはずです。

Outputclusterissuer.certmanager.k8s.io/letsencrypt-prod created

この新しい発行者を使用するようにecho_ingress.yamlを更新します。

nano echo_ingress.yaml

ファイルに次の変更を加えます。

echo_ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: echo-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - echo1.example.com
    - echo2.example.com
    secretName: letsencrypt-prod
  rules:
  - host: echo1.example.com
    http:
      paths:
      - backend:
          serviceName: echo1
          servicePort: 80
  - host: echo2.example.com
    http:
      paths:
      - backend:
          serviceName: echo2
          servicePort: 80

ここでは、ClusterIssuerとシークレット名の両方をletsencrypt-prodに更新します。

変更に満足したら、ファイルを保存して閉じます。

kubectl applyを使用して変更をロールアウトします。

kubectl apply -f echo_ingress.yaml
Outputingress.extensions/echo-ingress configured

Let's Encrypt運用サーバーが証明書を発行するまで数分待ちます。 certificateオブジェクトでkubectl describeを使用して、進行状況を追跡できます。

kubectl describe certificate letsencrypt-prod

次の出力が表示されたら、証明書は正常に発行されています。

OutputEvents:
  Type    Reason         Age   From          Message
  ----    ------         ----  ----          -------
  Normal  Generated      82s   cert-manager  Generated new private key
  Normal  OrderCreated   82s   cert-manager  Created Order resource "letsencrypt-prod-2626449824"
  Normal  OrderComplete  37s   cert-manager  Order "letsencrypt-prod-2626449824" completed successfully
  Normal  CertIssued     37s   cert-manager  Certificate issued successfully

次に、curlを使用してテストを実行し、HTTPSが正しく機能していることを確認します。

curl echo1.example.com

以下が表示されるはずです。

Output
308 Permanent Redirect

308 Permanent Redirect


nginx/1.15.9

これは、HTTP要求がHTTPSを使用するようにリダイレクトされていることを示します。

https://echo1.example.comcurlを実行します。

curl https://echo1.example.com

次の出力が表示されます。

Outputecho1

詳細な-vフラグを指定して前のコマンドを実行すると、証明書のハンドシェイクをさらに深く掘り下げて、証明書情報を確認できます。

この時点で、Nginx IngressのLet's Encrypt証明書を使用してHTTPSを正常に設定できました。

結論

このガイドでは、Nginx Ingressを設定して、Kubernetesクラスター内のバックエンドサービスに外部要求を負荷分散およびルーティングします。 また、cert-manager証明書プロビジョナーをインストールし、2つのホストパスのLet's Encrypt証明書を設定することにより、イングレスを保護しました。

Nginx Ingress Controllerには多くの代替手段があります。 詳細については、Kubernetesの公式ドキュメントのIngress controllersを参照してください。