アプリケーション開発の最終的な目標は、もちろん、インターネット上でアプリケーションを公開することです。 開発者にとって、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 created
ClusterIssuer がデプロイされ、準備ができていることを確認します ( READY
フィールドの値がTrue
です)。
$ kubectl get clusterissuerNAME READY AGE
example-issuer True 3h9m
cert-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 created
Cafe アプリケーション用に 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 created
DNS 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。"