アプリケーション開発の最終的な目標は、もちろん、インターネット上でアプリケーションを公開することです。 開発者にとって、Kubernetes は、アプリケーションへのリクエストをルーティングするメカニズムとして Ingress コントローラーを提供することで、このプロセスをある程度簡素化します。 ただし、すべてが期待どおりにセルフサービスであるとは限りません。アプリのドメイン名を Ingress コントローラーの IP アドレスにマッピングするためのドメイン ネーム システム (DNS) のレコードと、HTTPS を使用して接続を保護するための TLS 証明書が必要です。 ほとんどの組織では、DNS や TLS を自分で所有していないため、それらを所有する運用グループ (または複数のグループ) と調整する必要があります。
オペレーターにとって物事は必ずしも簡単ではありません。 ほとんどの組織では、DNS レコードを更新する必要性はほとんどないため、手順(ビジネス ルールと実際の技術的な手順の両方)がほとんどないか、まったく存在しない傾向があります。 つまり、DNS レコードを追加する必要がある場合は、まずドキュメントを探すか、同僚に尋ねるか、(最悪の場合)自分で調べる必要があります。 また、企業のセキュリティ ルールに準拠していること、およびファイアウォールに対してイングレスが適切にタグ付けされていることを確認する必要があります。
幸いなことに、開発者とオペレーターの両方の生活を楽にする方法があります。 この記事では、オペレーターが Kubernetes デプロイメントを構成して、開発者が Kubernetes 環境で DNS レコードを更新し、TLS 証明書を生成できるようにセルフサービスを有効にする方法を説明します。 事前にインフラストラクチャを構築することで、必要なビジネス要件と技術要件がすべて満たされていることを保証できます。
ソリューションを導入すれば、開発者がアプリケーションをインターネットに公開するために必要なことは、Kubernetes インストールによって管理されるドメイン内の完全修飾ドメイン名 (FQDN) を含む提供されたテンプレートに従って Ingress コントローラーを作成することだけです。 Kubernetes はテンプレートを使用して Ingress コントローラーの IP アドレスを割り当て、FQDN を IP アドレスにマッピングする DNS Aレコードを作成し、FQDN の TLS 証明書を生成して Ingress コントローラーに追加します。 クリーンアップも同様に簡単です。Ingress が削除されると、DNS レコードがクリーンアップされます。 
このソリューションでは、次のテクノロジーを活用しています (インストールと構成の手順については以下を参照してください)。
ソリューションを構成する前に、次のものが必要です。
LoadBalancer ) オブジェクトを備えた Kubernetes クラウド インストール。 このソリューションでは Linode を使用しますが、他のクラウド プロバイダーも機能します。kubectl 。また、Kubernetes の基本的な知識 (マニフェストの適用方法、Helm チャートの使用方法、 kubectlコマンドを発行して出力を表示してトラブルシューティングする方法) があることも前提としています。 Let's Encrypt の基本的な概念を理解しておくと役立ちますが、必須ではありません。概要については、ブログをご覧ください。 また、 cert-manager がどのように機能するかを知る必要はありませんが、cert-manager (および一般的な証明書) が NGINX Ingress Controller でどのように機能するかに興味がある場合は、最近の投稿「Kubernetes 環境での証明書管理の自動化」を参照してください。
このソリューションは macOS と Linux の両方でテストされています。 Windows Subsystem for Linuxバージョン 2 (WSL2) ではテストしていませんが、問題は発生しないと思われます。
注記: このソリューションは概念実証のサンプルとして提供されており、実稼働環境での使用を目的としたものではありません。 特に、運用とセキュリティに関するベストプラクティスがすべて組み込まれているわけではありません。 これらのトピックの詳細については、 cert-managerおよびExternalDNS のドキュメントを参照してください。
ソリューションを展開するには、次のセクションの手順に従います。
NGINX Ingress Controller リポジトリをクローンします。
$ git clone https://github.com/nginxinc/kubernetes-ingress.gitCloning into 'kubernetes-ingress'...
remote: Enumerating objects: 45176, done.
remote: Counting objects: 100% (373/373), done.
remote: Compressing objects: 100% (274/274), done.
remote: Total 45176 (delta 173), reused 219 (delta 79), pack-reused 44803
Receiving objects: 100% (45176/45176), 60.45 MiB | 26.81 MiB/s, done.
Resolving deltas: 100% (26592/26592), done.Kubernetes クラスターに接続できることを確認します。
$ kubectl cluster-infoKubernetes control plane is running at https://ba35bacf-b072-4600-9a04-e04...6a3d.us-west-2.linodelke.net:443
KubeDNS is running at https://ba35bacf-b072-4600-9a04-e04...6a3d.us-west-2.linodelke.net:443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
 
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.Helm を使用して、NGINX Ingress Controller をデプロイします。 3 つの非標準構成オプションを追加していることに注意してください。
controller.enableCustomResources – HelmにNGINXのVirtualServerとVirtualServerRouteカスタムリソースを作成するためのカスタムリソース定義(CRD)をインストールさせます。controller.enableCertManager – NGINX Ingress Controller がcert-managerコンポーネントと通信するように構成します。controller.enableExternalDNS – Ingress コントローラーが ExternalDNS コンポーネントと通信するように構成します。$ helm install nginx-kic nginx-stable/nginx-ingress --namespace nginx-ingress  --set controller.enableCustomResources=true --create-namespace  --set controller.enableCertManager=true --set controller.enableExternalDNS=trueNAME: nginx-kic
LAST DEPLOYED: Day Mon  DD hh:mm:ss YYYY
NAMESPACE: nginx-ingress
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
The NGINX Ingress Controller has been installed.NGINX Ingress Controller が実行中であることを確認し、 EXTERNAL-IPフィールドの値をメモします。これは、NGINX Ingress Controller の IP アドレスです (ここではwww.xxx.yyy.zzz )。 読みやすくするために、出力は 2 行に分割されます。
$ kubectl get services --namespace nginx-ingressNAME                      TYPE           CLUSTER-IP      ...
nginx-kic-nginx-ingress   LoadBalancer   10.128.152.88   ... 
   ... EXTERNAL-IP       PORT(S)                      AGE
   ... www.xxx.yyy.zzz   80:32457/TCP,443:31971/TCP   3h8mこのソリューションでは、 cert-manager はTLS 証明書を取得するときにDNS-01チャレンジ タイプを使用します。これには、 ClusterIssuer リソースの作成中に Cloudflare API トークンを提供する必要があります。 このソリューションでは、API トークンは Kubernetes Secretとして提供されます。
Helm を使用してcert-manager をデプロイします。
$ helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.9.1  --set installCRDs=trueNAME: cert-manager
LAST DEPLOYED: Day Mon  DD hh:mm:ss YYYY
NAMESPACE: cert-manager
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
cert-manager v1.9.1 has been deployed successfully!Cloudflare APIトークンをKubernetes Secretとしてデプロイし、 <API トークン>:
$ kubectl apply -f - <<EOFapiVersion: v1
kind: Secret
metadata:
  name: Cloudflare-api-token-secret
  namespace: cert-manager
type: Opaque
stringData:
  api-token: "<your-API-token>"
EOF
secret/Cloudflare-api-token-secret createdトークンを取得する場所としてCloudflare-api-token-secret (前の手順で定義) を指定して、ClusterIssuer オブジェクトを作成します。 必要に応じて、 metadata.nameフィールドのexample-issuer (およびspec.acme.privateKeySecretRef.nameフィールドのexample-issuer-account-key ) を別の名前に置き換えることができます。
$ kubectl apply -f - <<EOFapiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: example-issuer
  namespace: cert-manager
spec:
  acme:
    email: example@example.com
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: example-issuer-account-key
    solvers:
      - dns01:
          Cloudflare:
            apiTokenSecretRef:
              name: Cloudflare-api-token-secret
              key: api-token
EOF
clusterissuer.cert-manager.io/example-issuer createdClusterIssuer がデプロイされ、準備ができていることを確認します ( READYフィールドの値がTrueです)。
$ kubectl get clusterissuerNAME             READY   AGE
example-issuer   True    3h9mcert-manager と同様に、ExternalDNS プロジェクトでは DNS を管理するために Cloudflare API トークンが必要です。 両方のプロジェクトに同じトークンを使用できますが、必須ではありません。
プロジェクト間の統合を可能にするために、NGINX Ingress Controller の ExternalDNS CRD を作成します。
$ kubectl create -f ./kubernetes-ingress/deployments/common/crds/externaldns.nginx.org_dnsendpoints.yamlcustomresourcedefinition.apiextensions.k8s.io/dnsendpoints.externaldns.nginx.org created外部 DNS サービス ( external-dns ) を作成します。 マニフェストはかなり長いため、ここでは 2 つの部分に分割します。 最初の部分では、アカウント、ロール、および権限を構成します。
external-dnsという ServiceAccount オブジェクトを作成します。external-dnsとも呼ばれます) を作成します。$ kubectl apply -f - <<EOFapiVersion: v1
kind: ServiceAccount
metadata:
  name: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: external-dns
rules:
- apiGroups: [""]
  resources: ["services","endpoints","pods"]
  verbs: ["get","watch","list"]
- apiGroups: ["extensions","networking.k8s.io"]
  resources: ["ingresses"]
  verbs: ["get","watch","list"]
- apiGroups: ["externaldns.nginx.org"]
  resources: ["dnsendpoints"]
  verbs: ["get","watch","list"]
- apiGroups: ["externaldns.nginx.org"]
  resources: ["dnsendpoints/status"]
  verbs: ["update"]
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["list","watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: external-dns-viewer
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: external-dns
subjects:
- kind: ServiceAccount
  name: external-dns
  namespace: default
EOF
serviceaccount/external-dns created
clusterrole.rbac.authorization.k8s.io/external-dns created
clusterrolebinding.rbac.authorization.k8s.io/external-dns-viewer createdマニフェストの 2 番目の部分では、ExternalDNS デプロイメントを作成します。
domain-filter をexample.comに設定します。CF_API_TOKEN環境変数を Cloudflare API トークンに設定します。 のために <API トークン>実際のトークンまたはトークンを含む Secret のいずれかを置き換えます。 後者の場合、環境変数を使用してSecret をコンテナーに投影する必要もあります。FREE_TIER環境変数を「true」に設定します (有料の Cloudflare サブスクリプションがない限り適切です)。$  kubectl apply -f - <<EOF 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: external-dns
  template:
    metadata:
      labels:
        app: external-dns
    spec:
      serviceAccountName: external-dns
      containers:
      - name: external-dns
        image: k8s.gcr.io/external-dns/external-dns:v0.12.0
        args:
        - --source=service
        - --source=ingress
        - --source=crd
        - --crd-source-apiversion=externaldns.nginx.org/v1
        - --crd-source-kind=DNSEndpoint
        - --domain-filter=example.com
        - --provider=Cloudflare
        env:
          - name: CF_API_TOKEN
            value: "<your-API-token>"
          - name: FREE_TIER
            value: "true"
EOF
serviceaccount/external-dns created
clusterrole.rbac.authorization.k8s.io/external-dns created
clusterrolebinding.rbac.authorization.k8s.io/external-dns-viewer created
deployment.apps/external-dns createdテスト目的で、 Cafeと呼ばれる標準の NGINX Ingress Controller サンプル アプリケーションを使用します。
Cafe アプリケーションをデプロイします。
$ kubectl apply -f ./kubernetes-ingress/examples/ingress-resources/complete-example/cafe.yamldeployment.apps/coffee created
service/coffee-svc created
deployment.apps/tea created
service/tea-svc createdCafe アプリケーション用に NGINX Ingress Controller をデプロイします。 次の設定に注意してください。
親切: VirtualServer – 標準の Kubernetes Ingress リソースではなく、NGINX VirtualServer カスタム リソースを使用しています。spec.host – cafe.example.comを、デプロイするホストの名前に置き換えます。 ホストは、ExternalDNS で管理されているドメイン内にある必要があります。spec.tls.cert-manager.cluster-issuer – この投稿で指定された値を使用している場合、これはexample-issuerです。 必要に応じて、 「cert‑manager の展開」の手順 3で選択した名前を置き換えます。spec.externalDNS.enable – 値true は、 ExternalDNS に DNS Aレコードを作成するように指示します。Kubernetes はプロバイダーの DNS API と対話するため、このステップが完了するまでの時間は DNS プロバイダーに大きく依存することに注意してください。
$ kubectl apply -f - <<EOFapiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
  name: cafe
spec:
  host: cafe.example.com
  tls:
    secret: cafe-secret
    cert-manager:
      cluster-issuer: example-issuer
  externalDNS:
    enable: true
  upstreams:
  - name: tea
    service: tea-svc
    port: 80
  - name: coffee
    service: coffee-svc
    port: 80
  routes:
  - path: /tea
    action:
      pass: tea
  - path: /coffee
    action:
      pass: coffee
EOF
virtualserver.k8s.nginx.org/cafe createdDNS Aレコードを確認します。特に、 ANSWER SECTIONブロックで FQDN (ここではcafe.example.com ) が正しい IP アドレス ( www.xxx.yyy.zzz ) にマッピングされていることを確認します。 
$ dig cafe.example.com 
; <<>> DiG 9.10.6 <<>> cafe.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22633
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
 
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;cafe.example.com.		IN	A
 
;; ANSWER SECTION:
cafe.example.com.	279	IN	A	www.xxx.yyy.zzz
 
;; Query time: 1 msec
;; SERVER: 2607:fb91:119b:4ac4:2e0:xxxx:fe1e:1359#53(2607:fb91:119b:4ac4:2e0:xxxx:fe1e:1359)
;; WHEN: Day Mon  DD hh:mm:ss TZ YYYY
;; MSG SIZE  rcvd: 67証明書が有効であることを確認します( READYフィールドの値がTrueです)。
$ kubectl get certificatesNAME          READY   SECRET        AGE
cafe-secret   True    cafe-secret   8m51sアプリケーションにアクセスできることを確認します。
$ curl https://cafe.example.com/coffeeServer address: 10.2.2.4:8080
Server name: coffee-7c86d7d67c-lsfs6
Date: DD/Mon/YYYY:hh:mm:ss +TZ-offset
URI: /coffee
Request ID: 91077575f19e6e735a91b9d06e9684cd
$ curl https://cafe.example.com/tea
Server address: 10.2.2.5:8080
Server name: tea-5c457db9-ztpns
Date: DD/Mon/YYYY:hh:mm:ss +TZ-offset
URI: /tea
Request ID: 2164c245a495d22c11e900aa0103b00fソリューションが導入されると、裏では多くのことが起こります。 この図は、開発者が NGINX VirtualServer カスタム リソースを使用して NGINX Ingress Controller をデプロイした場合に何が起こるかを示しています。 一部の操作詳細は省略されていることに注意してください。
Aレコードを作成します。Aレコードを作成しますKubernetes の複雑さと使用しているコンポーネントを考慮すると、包括的なトラブルシューティング ガイドを提供することは困難です。 そうは言っても、問題を特定するのに役立つ基本的な提案がいくつかあります。
kubectl getコマンドとkubectl describeコマンドを使用して、デプロイされたオブジェクトの構成を検証します。kubectl ログ <コンポーネント> デプロイされたさまざまなコンポーネントのログ ファイルを表示するコマンド。それでも問題が解決しない場合は、 NGINXCommunity Slackで私たちを見つけてサポートを求めてください。 私たちのコミュニティは活気に満ちており、いつでも喜んで問題を解決します。
NGINX Plus をベースにした NGINX Ingress Controller を試すには、今すぐ30 日間の無料トライアルを開始するか、弊社にお問い合わせの上、使用事例についてご相談ください。
「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 q。"