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-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サービスがポート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.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.comとecho2.example.comの本番証明書を展開できます。 これを行うには、letsencrypt-prodClusterIssuerを使用します。
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を設定する方法を参照してください。