DigitalOceanKubernetesでCert-Managerを使用してNginxIngressを設定する方法

提供:Dev Guides
移動先:案内検索

序章

Kubernetes Ingresses を使用すると、Kubernetesクラスターの外部からクラスター内のサービスにトラフィックを柔軟にルーティングできます。 これは、HTTPおよびHTTPSトラフィックをKubernetesサービスにルーティングするためのルールを定義するIngress Resources と、トラフィックを負荷分散して適切な場所にルーティングすることでルールを実装するIngress Controllersを使用して実現されます。バックエンドサービス。

人気のあるIngressControllerには、 NginxContourHAProxy 、およびTraefikが含まれます。 入力は、それぞれが専用のロードバランサーを使用する複数のLoadBalancerサービスを設定するためのより効率的で柔軟な代替手段を提供します。

このガイドでは、Kubernetesで管理されている Nginx Ingress Controller をセットアップし、トラフィックをいくつかのダミーバックエンドサービスにルーティングするためのいくつかのIngressリソースを作成します。 Ingressをセットアップしたら、 cert-manager をクラスターにインストールして、IngressへのHTTPトラフィックを暗号化するためのTLS証明書を管理およびプロビジョニングします。 このガイドでは、Helmパッケージマネージャーを使用しません。 Helmを使用してNginxIngressControllerをロールアウトするためのガイドについては、Helmを使用してDigitalOceanKubernetesでNginxIngressをセットアップする方法を参照してください。

前提条件

このガイドを開始する前に、次のものを利用できるようにしておく必要があります。

  • ロールベースのアクセス制御(RBAC)が有効になっているKubernetes1.15+クラスター。 このセットアップではDigitalOceanKubernetes クラスターを使用しますが、別の方法を使用してクラスターを自由に作成できます。
  • kubectlコマンドラインツールがローカルマシンにインストールされ、クラスターに接続するように構成されています。 kubectl のインストールについて詳しくは、公式ドキュメントをご覧ください。 DigitalOcean Kubernetesクラスターを使用している場合は、 DigitalOcean Kubernetesクラスターへの接続方法を参照して、kubectlを使用してクラスターに接続する方法を確認してください。
  • Ingressが使用するDigitalOceanロードバランサーを指すことができるドメイン名とDNSAレコード。 DigitalOceanを使用してドメインのDNSレコードを管理している場合は、 DNSレコードの管理方法を参照して、Aレコードの作成方法を確認してください。
  • ローカルマシンにインストールされているwgetコマンドラインユーティリティ。 オペレーティングシステムに組み込まれているパッケージマネージャーを使用して、wgetをインストールできます。

これらのコンポーネントを設定したら、このガイドを開始する準備が整います。

ステップ1—ダミーバックエンドサービスの設定

Ingress Controllerを展開する前に、まず2つのダミーエコーサービスを作成して展開し、Ingressを使用して外部トラフィックをルーティングします。 echo Servicesは、 hashcorp / http-echo Webサーバーコンテナを実行します。このコンテナは、Webサーバーの起動時に渡されたテキスト文字列を含むページを返します。 http-echoの詳細については、その GitHubリポジトリを参照してください。また、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のデフォルトポートにルーティングします。

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

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

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

kubectl apply -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   <none>        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つだけ作成します。 textパラメーターをecho2に設定して、Webサーバーがテキストecho2を返すようにします。

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

kubectl apply -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   <none>        80/TCP    6m6s
echo2        ClusterIP   10.245.128.224   <none>        80/TCP    6m3s
kubernetes   ClusterIP   10.245.0.1       <none>        443/TCP   4d21h

ダミーのエコーWebサービスが稼働しているので、NginxIngressControllerの展開に進むことができます。

手順2— Kubernetes NginxIngressControllerを設定する

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

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

この場合、IngressControllerをDigitalOceanKubernetesクラスターにデプロイしているため、コントローラーは、すべての外部トラフィックが送信されるDigitalOceanロードバランサーをプロビジョニングするLoadBalancerサービスを作成します。 このロードバランサーは、外部トラフィックをNginxを実行しているIngress Controller Podにルーティングし、Nginxはトラフィックを適切なバックエンドサービスに転送します。

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

注:このチュートリアルでは、 DigitalOceanProviderの公式インストール手順に従います。 Kubernetesプロバイダーに応じて適切なマニフェストファイルを選択する必要があります。


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

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/do/deploy.yaml

ここではapplyを使用して、将来、IngressControllerオブジェクトを完全に上書きするのではなくapplyの変更を段階的に変更できるようにします。 applyの詳細については、Kubernetesの公式ドキュメントからリソースの管理を参照してください。

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

Outputnamespace/ingress-nginx created
serviceaccount/ingress-nginx created
configmap/ingress-nginx-controller created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
service/ingress-nginx-controller-admission created
service/ingress-nginx-controller created
deployment.apps/ingress-nginx-controller created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
serviceaccount/ingress-nginx-admission created

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

IngressControllerポッドが開始したことを確認します。

kubectl get pods -n ingress-nginx \
  -l app.kubernetes.io/name=ingress-nginx --watch
OutputNAME                                       READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-l2jhk       0/1     Completed   0          13m
ingress-nginx-admission-patch-hsrzf        0/1     Completed   0          13m
ingress-nginx-controller-c96557986-m47rq   1/1     Running     0          13m

CTRL+Cを押して、プロンプトに戻ります。

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

kubectl get svc --namespace=ingress-nginx

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

OutputNAME                                 TYPE           CLUSTER-IP       EXTERNAL-IP       PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.245.201.120   203.0.113.0   80:31818/TCP,443:31146/TCP   14m
ingress-nginx-controller-admission   ClusterIP      10.245.239.119   <none>            443/TCP                      14m

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

注:デフォルトでは、Nginx IngressLoadBalancerサービスのservice.spec.externalTrafficPolicyは値Localに設定されており、すべてのロードバランサートラフィックがNginxIngressPodを実行しているノードにルーティングされます。 他のノードは、ロードバランサーのヘルスチェックに意図的に失敗するため、入力トラフィックはそれらにルーティングされません。 外部トラフィックポリシーはこのチュートリアルの範囲を超えていますが、詳細については、Kubernetes外部トラフィックポリシーの詳細およびType =LoadBalancerのサービスのソースIPを公式から参照できます。 Kubernetesドキュメント。


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

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

ステップ3—入力リソースを作成する

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

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

まず、 echo1.example.com宛てのトラフィックをecho1バックエンドサービスにルーティングし、echo2.example.com宛てのトラフィックをにルーティングする簡単なルールを作成します。 echo2バックエンドサービス。

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

nano echo_ingress.yaml

次の入力定義を貼り付けます。

echo_ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echo-ingress
spec:
  rules:
  - host: echo1.example.com
    http:
        paths:
        - pathType: Prefix
          path: "/"
          backend:
            service:
              name: echo1
              port:
                number: 80
  - host: echo2.example.com
    http:
        paths:
        - pathType: Prefix
          path: "/"
          backend:
            service:
              name: echo2
              port:
                number: 80

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

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

これで、kubectlを使用してイングレスを作成できます。

kubectl apply -f echo_ingress.yaml

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

Outputingress.networking.k8s.io/echo-ingress created

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

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

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

curl echo1.example.com

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

Outputecho1

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

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

curl echo2.example.com

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

Outputecho2

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

この時点で、仮想ホストベースのルーティングを実行するための最小限のNginxIngressを正常に設定できました。 次のステップでは、 cert-manager をインストールして、IngressのTLS証明書をプロビジョニングし、より安全なHTTPSプロトコルを有効にします。

ステップ4—Cert-Managerのインストールと構成

このステップでは、cert-managerのv1.7.1をクラスターにインストールします。 cert-managerは、 Let's Encrypt およびその他の認証局(CA)からTLS証明書をプロビジョニングし、それらのライフサイクルを管理するKubernetesアドオンです。 Ingressリソースに注釈を付け、Ingress仕様にtlsセクションを追加し、1つ以上のIssuersまたはClusterIssuersを構成して、優先するものを指定することにより、証明書を自動的に要求および構成できます。証明する機関。 IssuerおよびClusterIssuerオブジェクトの詳細については、Issuerの公式のcert-managerドキュメントを参照してください。

公式のインストール手順に従って、cert-managerとそのカスタムリソース定義(CRD)(発行者やClusterIssuersなど)をインストールします。 cert-managerという名前空間が作成され、そこにcert-managerオブジェクトが作成されることに注意してください。

kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.7.1/cert-manager.yaml

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

Outputcustomresourcedefinition.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
. . .
deployment.apps/cert-manager-webhook created
mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created
validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created

インストールを確認するには、実行中のポッドのcert-manager名前空間を確認してください。

kubectl get pods --namespace cert-manager
OutputNAME                                       READY   STATUS    RESTARTS   AGE
cert-manager-578cd6d964-hr5v2              1/1     Running   0          99s
cert-manager-cainjector-5ffff9dd7c-f46gf   1/1     Running   0          100s
cert-manager-webhook-556b9d7dfd-wd5l6      1/1     Running   0          99s

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

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

テストClusterIssuerを作成して、証明書プロビジョニングメカニズムが正しく機能していることを確認しましょう。 ClusterIssuerは名前空間スコープではなく、任意の名前空間のCertificateリソースで使用できます。

お気に入りのテキストエディタでstaging_issuer.yamlという名前のファイルを開きます。

nano staging_issuer.yaml

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

staging_issuer.yaml

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
 name: letsencrypt-staging
 namespace: cert-manager
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
   solvers:
   - http01:
       ingress:
         class:  nginx

ここでは、letsencrypt-stagingというClusterIssuerを作成し、Let'sEncryptステージングサーバーを使用することを指定します。 後で本番サーバーを使用して証明書をロールアウトしますが、本番サーバーはそれに対して行われるリクエストをレート制限するため、テスト目的ではステージングURLを使用する必要があります。

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

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

kubectl create -f staging_issuer.yaml

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

Outputclusterissuer.cert-manager.io/letsencrypt-staging created

このプロセスを繰り返して、本番のClusterIssuerを作成します。 証明書は、前の手順でプロビジョニングされたIngressリソースに注釈を付けて更新した後にのみ作成されることに注意してください。

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

nano prod_issuer.yaml

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

prod_issuer.yaml

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
  namespace: cert-manager
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
    solvers:
    - http01:
        ingress:
          class: nginx

別のACMEサーバーのURLとletsencrypt-prodシークレットキー名に注意してください。

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

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

kubectl create -f prod_issuer.yaml

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

Outputclusterissuer.cert-manager.io/letsencrypt-prod created

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

DigitalOcean Kubernetesを使用している場合は、最初に回避策を実装して、ポッドがIngressを使用して他のポッドと通信できるようにする必要があります。 DigitalOcean Kubernetesを使用していない場合は、ステップ6に進んでください。

ステップ5—ロードバランサーを介したポッド通信の有効化(オプション)

Let's Encryptから証明書をプロビジョニングする前に、cert-managerは最初にセルフチェックを実行して、Let'sEncryptがドメインを検証するcert-managerポッドに到達できることを確認します。 このチェックをDigitalOceanKubernetesに渡すには、NginxIngressロードバランサーを介したポッド-ポッド通信を有効にする必要があります。

これを行うには、クラウドロードバランサーの外部IPを指すDNS Aレコードを作成し、このサブドメインでNginxIngressServiceマニフェストに注釈を付けます。

DNS管理サービスに移動することから始めて、DigitalOceanロードバランサーの外部IPを指すworkaround.example.comのAレコードを作成します。 ロードバランサーの外部IPは、手順2で取得したingress-nginxサービスの外部IPアドレスです。 DigitalOceanを使用してドメインのDNSレコードを管理している場合は、 DNSレコードの管理方法を参照して、Aレコードの作成方法を確認してください。 ここではサブドメインworkaroundを使用していますが、任意のサブドメインを自由に使用できます。

Ingressロードバランサーを指すDNSレコードを作成したので、IngressLoadBalancerサービスにdo-loadbalancer-hostnameアノテーションを付けます。 お気に入りのエディターでingress_nginx_svc.yamlという名前のファイルを開き、次のLoadBalancerマニフェストに貼り付けます。

ingress_nginx_svc.yaml

apiVersion: v1
kind: Service
metadata:
  annotations:
    service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol: 'true'
    service.beta.kubernetes.io/do-loadbalancer-hostname: "workaround.example.com"
  labels:
    helm.sh/chart: ingress-nginx-4.0.6
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: http
    - name: https
      port: 443
      protocol: TCP
      targetPort: https
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller

このサービスマニフェストは、手順2でインストールした完全なNginxIngressマニフェストファイルから抽出されました。 インストールしたNginxIngressバージョンに対応するサービスマニフェストを必ずコピーしてください。 このチュートリアルでは、これは1.1.1です。 また、必ずdo-loadbalancer-hostnameアノテーションをworkaround.example.comドメインに設定してください。

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

kubectl applyを使用して、実行中のingress-nginx-controllerサービスを変更します。

kubectl apply -f ingress_nginx_svc.yaml

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

Outputservice/ingress-nginx-controller configured

これにより、ingress-nginx-controllerサービスに注釈が付けられ、クラスター内のポッドがこのingress-nginx-controllerロードバランサーを使用して相互に通信できるようになります。

ステップ6—ステージングと本番の発行証明書を暗号化しましょう

ドメインのステージングTLS証明書を発行するために、ステップ4で作成したClusterIssuerでecho_ingress.yamlに注釈を付けます。 これは、 ingress-shim を使用して、Ingressマニフェストで指定されたドメインの証明書を自動的に作成して発行します。

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

nano echo_ingress.yaml

Ingressリソースマニフェストに以下を追加します。

echo_ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echo-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-staging"
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
  - hosts:
    - echo1.example.com
    - echo2.example.com
    secretName: echo-tls
  rules:
    - host: echo1.example.com
      http:
        paths:
          - pathType: Prefix
            path: "/"
            backend:
              service:
                name: echo1
                port:
                  number: 80
    - host: echo2.example.com
      http:
        paths:
          - pathType: Prefix
            path: "/"
            backend:
              service:
                name: echo2
                port:
                  number: 80

ここでは、cert-managerClusterIssuerをletsencrypt-stagingに設定するための注釈を追加します。これは、ステップ4で作成したテスト証明書ClusterIssuerです。 また、入力のタイプ(この場合はnginx)を説明する注釈を追加します。

また、tlsブロックを追加して、証明書を取得するホストを指定し、secretNameを指定します。 このシークレットには、TLS秘密鍵と発行された証明書が含まれます。 example.comは、DNSレコードを作成したドメインと必ず交換してください。

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

kubectl applyを使用して、この更新を既存のIngressオブジェクトにプッシュします。

kubectl apply -f echo_ingress.yaml

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

Outputingress.networking.k8s.io/echo-ingress configured

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

kubectl describe ingress
OutputEvents:
  Type    Reason             Age               From                      Message
  ----    ------             ----              ----                      -------
  Normal  UPDATE             6s (x3 over 80m)  nginx-ingress-controller  Ingress default/echo-ingress
  Normal  CreateCertificate  6s                cert-manager              Successfully created Certificate "echo-tls"

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

kubectl describe certificate

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

OutputEvents:
  Type    Reason     Age    From          Message
  ----    ------     ----   ----          -------
  Normal  Requested  64s    cert-manager  Created new CertificateRequest resource "echo-tls-vscfw"
  Normal  Issuing    40s    cert-manager  The certificate has been successfully issued

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

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

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

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

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

Output. . .
HTTP request sent, awaiting response... 308 Permanent Redirect
. . .
ERROR: cannot verify echo1.example.com's certificate, issued by ‘ERROR: cannot verify echo1.example.com's certificate, issued by ‘CN=(STAGING) Artificial Apricot R3,O=(STAGING) Let's Encrypt,C=US’:
  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の本番証明書を展開できます。 これを行うには、letsencrypt-prodClusterIssuerを使用します。

echo_ingress.yamlletsencrypt-prodを使用するように更新します。

nano echo_ingress.yaml

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

echo_ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echo-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
  - hosts:
    - echo1.example.com
    - echo2.example.com
    secretName: echo-tls
  rules:
    - host: echo1.example.com
      http:
        paths:
          - pathType: Prefix
            path: "/"
            backend:
              service:
                name: echo1
                port:
                  number: 80
    - host: echo2.example.com
      http:
        paths:
          - pathType: Prefix
            path: "/"
            backend:
              service:
                name: echo2
                port:
                  number: 80

ここでは、ClusterIssuerの名前をletsencrypt-prodに更新します。

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

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

kubectl apply -f echo_ingress.yaml
Outputingress.networking.k8s.io/echo-ingress configured

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

kubectl describe certificate echo-tls

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

Output Normal  Issuing    28s                 cert-manager  Issuing certificate as Secret was previously issued by ClusterIssuer.cert-manager.io/letsencrypt-staging
  Normal  Reused     28s                 cert-manager  Reusing private key stored in existing Secret resource "echo-tls"
  Normal  Requested  28s                 cert-manager  Created new CertificateRequest resource "echo-tls-49gmn"
  Normal  Issuing    2s (x2 over 4m52s)  cert-manager  The certificate has been successfully issued

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

curl echo1.example.com

次のように表示されます。

Output<html>
<head><title>308 Permanent Redirect</title></head>
<body>
<center><h1>308 Permanent Redirect</h1></center>
<hr><center>nginx/1.15.9</center>
</body>
</html>

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

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

curl https://echo1.example.com

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

Outputecho1

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

この時点で、NginxIngressのLet'sEncrypt証明書を使用してHTTPSを正常に構成できました。

結論

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

NginxIngressControllerには多くの選択肢があります。 詳細については、Kubernetesの公式ドキュメントのイングレスコントローラーを参照してください。

HelmKubernetesパッケージマネージャーを使用してNginxIngressControllerをロールアウトするためのガイドについては、Helmを使用してDigitalOceanKubernetesでNginxIngressを設定する方法を参照してください。