Knowledge Center Monthly Newsletter - March 2025
Stay up to date with the latest from the Knowledge Center. See all new and updated Knowledge Center articles published in the last month and re:Post’s top contributors.
Amazon EKS クラスターにある複数の Kubernetes サービスへの外部アクセスを提供する方法を教えてください。
Amazon Elastic Kubernetes Service (Amazon EKS) クラスターにある複数の Kubernetes サービスへの外部アクセスを提供したいと考えています。
簡単な説明
NGINX Ingress Controller または AWS Load Balancer Controller for Kubernetes を使用して、Amazon EKS クラスター内の複数の Kubernetes サービスへの外部アクセスを提供します。NGINX Ingress Controller は、主に NGINX によって管理されています。NGINX Ingress Controller で問題を確認するには、GitHub ウェブサイトの問題の一覧を参照してください。AWS Load Balancer Controller は、アマゾン ウェブ サービス (AWS) によって管理されています。AWS Load Balancer Controller の問題を確認するには、GitHub ウェブサイトの問題リストを参照してください。
重要: Ingress Controller および (Kubernetes ウェブサイトの) IngressClass は、(Kubernetes ウェブサイトの) Ingress とは異なります。Ingress は、クラスターの外部からクラスター内のサービスへの HTTP および HTTPS ルートを公開する Kubernetes リソースです。Ingress Controller が、通常はロードバランサーを使用して、入力を実行します。Ingress Controller なしで Ingress を使用することはできません。IngressClass は、Ingress オブジェクト要求を満たすために使用する Ingress Controller を識別するために使用されます。
前提条件:AWS Load Balancer Controller をインストールします。AWS Load Balancer Controller を使用して、Amazon EKS の LoadBalancer タイプのサービスオブジェクト用の Network Load Balancer を作成および管理するのがベストプラクティスです。
解決方法
次の解決策では、Kubernetes GitHub ウェブサイトの kubernetes/ingress-nginx Ingress Controller を使用します。公開されている他の Ingress Controller は、NGINX GitHub ウェブサイトの nginxinc/kubernetes-ingress です。
NGINX Ingress Controller for Kubernetes をデプロイする
NGINX Ingress Controller for Kubernetes は、伝送制御プロトコル (TCP) または Transport Layer Security (TLS) のいずれかによってデプロイできます。
**注意:**次の解決策は、Amazon EKS バージョン 1.22、NGINX Ingress Controller バージョン 1.3.0、および AWS Load Balancer Controller バージョン 2.4.3 でテストされています。
(オプション 1) Network Load Balancer の TCP 搭載 NGINX Ingress Controller
1. YAML ファイルを取得して、次の Kubernetes オブジェクトをデプロイします。namespace、serviceaccounts、configmap、clusterroles、clusterrolebindings、roles、rolebindings、services、deployments、ingressclasses、および validatingwebhookconfigurations。
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/aws/deploy.yaml
2. ファイルを編集します。次に、ingress-nginx-controller サービスオブジェクトセクションで、すべての service.beta.kubernetes.io アノテーションを以下に置き換えます。
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" service.beta.kubernetes.io/aws-load-balancer-type: "external" service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance" service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
3. マニフェストを適用します。
kubectl apply -f deploy.yaml
出力例:
namespace/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 ingressclass.networking.k8s.io/nginx created validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created serviceaccount/ingress-nginx-admission created clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
(オプション 2) NGINX ingress controller TLS termination on Network Load Balancer
デフォルトでは、前のソリューションは NGINX Ingress Controller で TLS を終了します。また、Network Load Balancer で TLS を終了するように NGINX Ingress サービスを設定することもできます。
1. deploy.yaml テンプレートをダウンロードします。
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml
2. ファイルを編集します。次に、 ingress-nginx-controller サービスオブジェクトセクションで、すべての service.beta.kubernetes.io アノテーションを以下に置き換えます。
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-west-2:XXXXXXXX:certificate/XXXXXX-XXXXXXX-XXXXXXX-XXXXXXXX service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443" service.beta.kubernetes.io/aws-load-balancer-type: "external" service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance" service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
**注意:**必ず service.beta.kubernetes.io/aws-load-balancer-ssl-cert の ARN を含めてください。
3. ファイルを編集し、Kubernetes クラスターの Amazon Virtual Private Cloud (Amazon VPC) CIDR を変更します。
proxy-real-ip-cidr: XXX.XXX.XXX/XX
4. マニフェストを適用します。
kubectl apply -f deploy.yaml
注意:前のマニフェストでは、 ExternalTrafficPolicy をローカルとして使用し、ソース (クライアント) の IP アドレスを保持しています。Amazon VPC でカスタム DHCP 名によりこの設定を使用すると、問題が発生します。この問題の発生を防ぐには、以下のパッチを kube-proxy に適用します。
kubectl edit daemonset kube-proxy -n kube-system
5. マニフェストを編集して、次のスニペットを含めます。
spec: template: spec: containers: - name: kube-proxy command: - kube-proxy - --hostname-override=$(NODE_NAME) - --v=2 - --config=/var/lib/kube-proxy-config/config env: - name: NODE_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: spec.nodeName
デプロイされたリソースを確認する
AWS Load Balancer Controller
コマンド:
kubectl get all -n kube-system --selector app.kubernetes.io/instance=aws-load-balancer-controller
出力例:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/aws-load-balancer-controller-85cd8965dc-ctkjt 1/1 Running 0 48m 192.168.37.36 ip-192-168-59-225.us-east-2.compute.internal none none pod/aws-load-balancer-controller-85cd8965dc-wpwx9 1/1 Running 0 48m 192.168.53.110 ip-192-168-59-225.us-east-2.compute.internal none> none NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR service/aws-load-balancer-webhook-service ClusterIP 10.100.154.44 none 443/TCP 19h app.kubernetes.io/instance=aws-load-balancer-controller,app.kubernetes.io/name=aws-load-balancer-controller NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR deployment.apps/aws-load-balancer-controller 2/2 2 2 19h aws-load-balancer-controller 602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon/aws-load-balancer-controller:v2.4.0 app.kubernetes.io/instance=aws-load-balancer-controller,app.kubernetes.io/name=aws-load-balancer-controller NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR replicaset.apps/aws-load-balancer-controller-85cd8965dc 2 2 2 19h aws-load-balancer-controller 602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon/aws-load-balancer-controller:v2.4.0 app.kubernetes.io/instance=aws-load-balancer-controller,app.kubernetes.io/name=aws-load-balancer-controller,pod-template-hash=85cd8965dc
NGINX Ingress Controller
コマンド:
kubectl get all -n ingress-nginx --selector app.kubernetes.io/instance=ingress-nginx
出力例:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/ingress-nginx-controller-54d8b558d4-k4pdf 1/1 Running 0 56m 192.168.46.241 ip-192-168-59-225.us-east-2.compute.internal none none NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR service/ingress-nginx-controller LoadBalancer 10.100.99.129 ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80:32578/TCP,443:30724/TCP 15h app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx service/ingress-nginx-controller-admission ClusterIP 10.100.190.61 none 443/TCP 15h app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR deployment.apps/ingress-nginx-controller 1/1 1 1 15h controller k8s.gcr.io/ingress-nginx/controller:v1.1.1@sha256:0bc88eb15f9e7f84e8e56c14fa5735aaa488b840983f87bd79b1054190e660de app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR replicaset.apps/ingress-nginx-controller-54d8b558d4 1 1 1 15h controller k8s.gcr.io/ingress-nginx/controller:v1.1.1@sha256:0bc88eb15f9e7f84e8e56c14fa5735aaa488b840983f87bd79b1054190e660de app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx,pod-template-hash=54d8b558d4 NAME COMPLETIONS DURATION AGE CONTAINERS IMAGES SELECTOR job.batch/ingress-nginx-admission-create 1/1 2s 15h create k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 controller-uid=242bdf56-de16-471d-a691-1ca1dbc10a41 job.batch/ingress-nginx-admission-patch 1/1 2s 15h patch k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 controller-uid=a9e710d2-5001-4d40-a435-ddc8993bfe42
IngressClass
コマンド:
kubectl get ingressclass
出力例:
NAME CONTROLLER PARAMETERS AGE alb ingress.k8s.aws/alb IngressClassParams.elbv2.k8s.aws/alb 19h nginx k8s.io/ingress-nginx none 15h
デプロイ設定をテストする
**注意:**次の手順では、2 つのマイクロサービスを実行しています。マイクロサービスは、デフォルトタイプとして Kubernetes を使用して内部に公開されます。
1. デプロイメントまたはマイクロサービスをセットアップします。例えば、hostname-app と apache-app などです。
hostname-app の hostname-app-svc.yaml ファイルの例:
apiVersion: apps/v1 kind: Deployment metadata: name: hostname-app namespace: default spec: replicas: 2 selector: matchLabels: app: hostname-app template: metadata: labels: app: hostname-app spec: containers: - name: hostname-app image: k8s.gcr.io/serve_hostname:1.1 --- apiVersion: v1 kind: Service metadata: name: hostname-svc namespace: default spec: ports: - port: 80 targetPort: 9376 protocol: TCP selector: app: hostname-app
apache-app の apache-app-svc.yaml ファイルの例:
apiVersion: apps/v1 kind: Deployment metadata: name: apache-app namespace: default spec: replicas: 2 selector: matchLabels: app: apache-app template: metadata: labels: app: apache-app spec: containers: - name: apache-app image: httpd:latest ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: apache-svc namespace: default labels: spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: app: apache-app
2. 設定を適用します。
hostname-app:
kubectl apply -f hostname-app-svc.yaml
apache-app:
kubectl apply -f apache-app-svc.yaml
3. リソースが作成されていることを確認します。
デプロイ
コマンド:
kubectl get deployment hostname-app apache-app -n default
出力例:
NAME READY UP-TO-DATE AVAILABLE AGE hostname-app 2/2 2 2 29m apache-app 2/2 2 2 29m
サービス
コマンド:
kubectl get svc apache-svc hostname-svc -n default
出力例:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE apache-svc ClusterIP 10.100.73.51 none 80/TCP 29m hostname-svc ClusterIP 10.100.100.44 none 80/TCP 29m
NGINX Ingress Controller をテストする
1. コマンドラインから以前に取得したロードバランサーの DNS URL にアクセスします。
curl -I ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com
出力例:
HTTP/1.1 404 Not Found Date: Thu, 03 Mar 2022 14:03:11 GMT Content-Type: text/html Content-Length: 146 Connection: keep-alive
**注意:**デフォルトのサーバーは、ingress ルールが定義されていないすべてのドメインリクエストに対して 404 Not Found ページを返します。Ingress Controller は、定義されたルールに基づいて、リクエストが設定と一致しない限り、指定されたバックエンドサービスにトラフィックを振り分けることはありません。host フィールドは Ingress オブジェクト用に設定されているため、同じホスト名でリクエストの Host ヘッダーを指定する必要があります。テスト環境では、curl フラグを使用して Host ヘッダーを指定します。本番環境では、ロードバランサーの DNS 名を Amazon Route 53 などの任意の DNS プロバイダーのホスト名にマッピングします。
2. Ingress を実装して、NGINX Ingress Controller によって提供される単一のロードバランサーを使用してサービスとインターフェイスで接続します。
micro-ingress.yaml の例:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: micro-ingress namespace: default annotations: kubernetes.io/ingress.class: nginx spec: rules: - host: hostname.mydomain.com http: paths: - backend: service: name: hostname-svc port: number: 80 path: / pathType: Prefix - host: apache.mydomain.com http: paths: - backend: service: name: apache-svc port: number: 80 path: / pathType: Prefix
注意: 詳細については、Kubernetes ウェブサイトの Name based virtual hosting を参照してください。
3. リソースが作成されていることを確認します。
Ingress
コマンド:
kubectl get ingress -n default
出力例:
NAME CLASS HOSTS ADDRESS PORTS AGE micro-ingress none hostname.mydomain.com,apache.mydomain.com ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80 29m
4. Host ヘッダーをリクエストに追加します。
最初に構成されたドメイン:
curl -i -H "Host: hostname.mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/
出力例:
HTTP/1.1 200 OK Date: Sat, 26 Mar 2022 18:50:38 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 29 Connection: keep-alive
2 番目に構成されたドメイン:
curl -i -H "Host: apache.mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/
出力例:
HTTP/1.1 200 OK Date: Sat, 26 Mar 2022 18:51:00 GMT Content-Type: text/html Content-Length: 45 Connection: keep-alive Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT ETag: "2d-432a5e4a73a80" Accept-Ranges: bytes
Host ヘッダーを追加すると、Ingress Controller は Ingressで定義した設定と一致するため、トラフィックをバックエンドで設定されたサービスにリダイレクトします。
同じドメイン名を維持したいが、アクセスしたパスに基づいてトラフィックを迂回させたい場合は、Ingress でパスベースのルーティングを追加する必要があります。
以下はその例です。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: path-ingress namespace: default annotations: kubernetes.io/ingress.class: nginxd nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: mydomain.com http: paths: - backend: service: name: hostname-svc port: number: 80 path: /hostname pathType: Prefix - host: mydomain.com http: paths: - backend: service: name: apache-svc port: number: 80 path: /apache pathType: Prefix
注意:リクエストに Host ヘッダーとして mydomain.com が含まれる場合、前の例では 200 レスポンスのみが返されます。リクエストは、/hostname または /apache パスでアクセスされます。他のすべてのリクエストでは、404 レスポンスが返されます。
5. パスベースのルーティングが追加されていることを確認します。
コマンド:
kubectl get ingress -n default
出力:
NAME CLASS HOSTS ADDRESS PORTS AGE micro-ingress none hostname.mydomain.com,apache.mydomain.com ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80 164m path-ingress none mydomain.com,mydomain.com ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80 120m
コマンド:
curl -i -H "Host: mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/hostname
- または -
curl -i -H "Host: mydomain.com" http://aaa71bxxxxx-11xxxxx10.us-east-2.elb.amazonaws.com/apache
AWS Load Balancer Controller を使用して Ingress をテストする
1. 次の例の Ingress マニフェストを使用して、Application Load Balancer を起動します。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: micro-ingress-alb namespace: default annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip spec: rules: - host: alb.hostname.mydomain.com http: paths: - backend: service: name: hostname-svc port: number: 80 path: / pathType: Prefix - host: alb.apache.mydomain.com http: - backend: service: name: apache-svc port: number: 80 path: / pathType: Prefix
2. Application Load Balancer が起動することを確認します。
コマンド:
kubectl get ingress -n default
出力:
NAME CLASS HOSTS ADDRESS PORTS AGE micro-ingress none hostname.mydomain.com,apache.mydomain.com ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80 164m micro-ingress-alb none alb.hostname.mydomain.com,alb.apache.mydomain.com k8s-default-microing-8a252bde81-1907206594.us-east-2.elb.amazonaws.com 80 18m path-ingress none mydomain.com,mydomain.com ad9bba7a8239a475297d24bd2f617782-a579e639079f8270.elb.us-east-2.amazonaws.com 80 120m
最初に構成されたドメインに基づくリクエスト:
curl -i -H "Host: alb.hostname.mydomain.com" http://k8s-default-microing-8a252bde81-1907206594.us-east-2.elb.amazonaws.com
出力例:
HTTP/1.1 200 OK Date: Sat, 26 Mar 2022 20:46:02 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 29 Connection: keep-alive
2 番目に構成されたドメインに基づくリクエスト:
curl -i -H "Host: alb.apache.mydomain.com" http://k8s-default-microing-8a252bde81-1907206594.us-east-2.elb.amazonaws.com
出力例:
HTTP/1.1 200 OK Date: Sat, 26 Mar 2022 20:46:14 GMT Content-Type: text/html Content-Length: 45 Connection: keep-alive Server: Apache/2.4.53 (Unix) Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT ETag: "2d-432a5e4a73a80" Accept-Ranges: bytes

関連するコンテンツ
- 質問済み 1年前lg...
- 質問済み 4ヶ月前lg...