DigitalOceanKubernetesでCert-Managerを使用してNginxIngressを設定する方法
序章
Kubernetes Ingresses を使用すると、Kubernetesクラスターの外部からクラスター内のサービスにトラフィックを柔軟にルーティングできます。 これは、HTTPおよびHTTPSトラフィックをKubernetesサービスにルーティングするためのルールを定義するIngress Resources と、トラフィックを負荷分散して適切な場所にルーティングすることでルールを実装するIngress Controllersを使用して実現されます。バックエンドサービス。
人気のあるIngressControllerには、 Nginx 、 Contour 、 HAProxy 、および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トラフィックを受け入れ、ポート5678
、http-echo
のデフォルトポートにルーティングします。
次に、echo1
とも呼ばれるデプロイメントを定義します。これは、app: echo1
LabelSelectorを使用してポッドを管理します。 デプロイメントには2つのポッドレプリカが必要であり、ポッドはhashicorp/http-echo
イメージを実行するecho1
というコンテナーを開始する必要があることを指定します。 text
パラメーターを渡し、それをecho1
に設定して、http-echo
Webサーバーが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
サービスがポート80
の10.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 IngressControllerのv1.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.com
DNSレコードを作成したら、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.com
とecho2.example.com
の本番証明書を展開できます。 これを行うには、letsencrypt-prod
ClusterIssuerを使用します。
echo_ingress.yaml
をletsencrypt-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.com
でcurl
を実行します。
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を設定する方法を参照してください。