Azure Kubernetes Service (AKS) でイングレス コントローラーを作成する

イングレス コントローラーは、リバース プロキシ、構成可能なトラフィック ルーティング、および Kubernetes サービスの TLS 終端を提供するソフトウェアです。 個別の Kubernetes サービスのイングレス ルールとルートを構成するには、Kubernetes イングレス リソースが使われます。 イングレス コントローラーとイングレス ルールを使用すれば、1 つの IP アドレスで Kubernetes クラスター内の複数のサービスにトラフィックをルーティングできます。

この記事では、Azure Kubernetes Service (AKS) クラスターに NGINX イングレス コントローラーを展開する方法について説明します。 続いて、それぞれが 1 つの IP アドレスでアクセスできる、2 つのアプリケーションを AKS クラスターで実行します。

Note

Nginx に基づく Kubernetes 用のオープンソース イングレス コントローラーは 2 つあります。1 つは Kubernetes コミュニティ (kubernetes/ingress-nginx) によって管理され、もう 1 つは NGINX, Inc. (nginxinc/kubernetes-ingress) によって管理されています。 この記事では、Kubernetes コミュニティのイングレス コントローラーを使用します。

または、次のこともできます。

開始する前に

この記事では、Helm 3 を使用して、サポートされているバージョンの Kubernetes に NGINX イングレス コントローラーをインストールします。 最新リリースの Helm を使用していること、および ingress-nginx の Helm リポジトリにアクセスできることを確認します。 この記事に記載されている手順は、以前のバージョンの Helm グラフ、NGINX イングレス コントローラー、または Kubernetes と互換性がない可能性があります。

この記事ではまた、Azure CLI バージョン 2.0.64 以降を実行していることも必要です。 バージョンを確認するには、az --version を実行します。 インストールまたはアップグレードする必要がある場合は、Azure CLI のインストールに関するページを参照してください。

また、この記事では、ACR が統合された既存の AKS クラスターがあることを前提としています。 ACR が統合された AKS クラスターを作成する方法の詳細については、Azure Kubernetes Service からの Azure Container Registry による認証に関する記事を参照してください。

基本構成

既定値をカスタマイズせずに単純な NGINX イングレス コントローラーを作成するには、helm を使用します。

NAMESPACE=ingress-basic

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

helm install ingress-nginx ingress-nginx/ingress-nginx --create-namespace --namespace $NAMESPACE 

上記の構成では、わかりやすくするために既定の構成が使用されています。 必要に応じて、デプロイをカスタマイズするためのパラメーター (例: --set controller.replicaCount=3) を追加できます。 次のセクションでは、イングレス コントローラーの高度にカスタマイズされた例を示します。

カスタマイズされた構成

次の一連の手順では、上のセクションで説明した基本的な構成の代わりに、カスタマイズされたイングレス コントローラーをデプロイする方法を示します。

Helm グラフで使用されるイメージを ACR にインポートする

イメージのバージョンを制御するには、独自の Azure Container Registry にイメージをインポートする必要があります。 NGINX イングレス コントローラー Helm グラフでは、3 つのコンテナー イメージを使用します。 これらのイメージを ACR にインポートするには、az acr import を使用します。

REGISTRY_NAME=<REGISTRY_NAME>
SOURCE_REGISTRY=k8s.gcr.io
CONTROLLER_IMAGE=ingress-nginx/controller
CONTROLLER_TAG=v1.0.4
PATCH_IMAGE=ingress-nginx/kube-webhook-certgen
PATCH_TAG=v1.1.1
DEFAULTBACKEND_IMAGE=defaultbackend-amd64
DEFAULTBACKEND_TAG=1.5

az acr import --name $REGISTRY_NAME --source $SOURCE_REGISTRY/$CONTROLLER_IMAGE:$CONTROLLER_TAG --image $CONTROLLER_IMAGE:$CONTROLLER_TAG
az acr import --name $REGISTRY_NAME --source $SOURCE_REGISTRY/$PATCH_IMAGE:$PATCH_TAG --image $PATCH_IMAGE:$PATCH_TAG
az acr import --name $REGISTRY_NAME --source $SOURCE_REGISTRY/$DEFAULTBACKEND_IMAGE:$DEFAULTBACKEND_TAG --image $DEFAULTBACKEND_IMAGE:$DEFAULTBACKEND_TAG

Note

コンテナー イメージを ACR にインポートするだけでなく、Helm Chart を ACR にインポートすることもできます。 詳細については、「Azure コンテナー レジストリに対する Helm グラフのプッシュおよびプル」を参照してください。

イングレス コントローラーを作成する

イングレス コントローラーを作成するには、Helm を使用して nginx-ingress をインストールします。 追加された冗長性については、NGINX イングレス コントローラーの 2 つのレプリカが --set controller.replicaCount パラメーターでデプロイされています。 イングレス コントローラーのレプリカの実行から十分にメリットを享受するには、AKS クラスターに複数のノードが存在していることを確認します。

イングレス コントローラーも Linux ノード上でスケジュールする必要があります。 Windows Server ノードでは、イングレス コントローラーを実行しないでください。 ノード セレクターは、--set nodeSelector パラメーターを使用して指定され、Linux ベース ノード上で NGINX イングレス コントローラーを実行するように Kubernetes スケジューラに指示されます。

ヒント

次の例では、ingress-basic という名前のイングレス リソースの Kubernetes 名前空間が作成され、その名前空間内で動作することを想定しています。 必要に応じて、ご自身の環境の名前空間を指定できます。

クラスター内のコンテナーへの要求でクライアント ソース IP の保持を有効にする場合は、Helm インストール コマンドに を追加します。 クライアント ソース IP が要求ヘッダーの X-Forwarded-For の下に格納されます。 クライアント ソース IP の保持が有効になっているイングレス コントローラーを使用する場合、SSL パススルーは機能しません。

# Add the ingress-nginx repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

# Set variable for ACR location to use for pulling images
ACR_URL=<REGISTRY_URL>

# Use Helm to deploy an NGINX ingress controller
helm install nginx-ingress ingress-nginx/ingress-nginx \
    --version 4.0.13 \
    --namespace ingress-basic --create-namespace \
    --set controller.replicaCount=2 \
    --set controller.nodeSelector."kubernetes\.io/os"=linux \
    --set controller.image.registry=$ACR_URL \
    --set controller.image.image=$CONTROLLER_IMAGE \
    --set controller.image.tag=$CONTROLLER_TAG \
    --set controller.image.digest="" \
    --set controller.admissionWebhooks.patch.nodeSelector."kubernetes\.io/os"=linux \
    --set controller.admissionWebhooks.patch.image.registry=$ACR_URL \
    --set controller.admissionWebhooks.patch.image.image=$PATCH_IMAGE \
    --set controller.admissionWebhooks.patch.image.tag=$PATCH_TAG \
    --set controller.admissionWebhooks.patch.image.digest="" \
    --set defaultBackend.nodeSelector."kubernetes\.io/os"=linux \
    --set defaultBackend.image.registry=$ACR_URL \
    --set defaultBackend.image.image=$DEFAULTBACKEND_IMAGE \
    --set defaultBackend.image.tag=$DEFAULTBACKEND_TAG \
    --set defaultBackend.image.digest=""

ロード バランサー サービスを確認する

次の出力例に示すように、NGINX イングレス コントローラーに対して Kubernetes ロード バランサー サービスが作成されると、動的パブリック IP アドレスが割り当てられます。

$ kubectl --namespace ingress-basic get services -o wide -w nginx-ingress-ingress-nginx-controller

NAME                                     TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)                      AGE   SELECTOR
nginx-ingress-ingress-nginx-controller   LoadBalancer   10.0.74.133   EXTERNAL_IP     80:32486/TCP,443:30953/TCP   44s   app.kubernetes.io/component=controller,app.kubernetes.io/instance=nginx-ingress,app.kubernetes.io/name=ingress-nginx

イングレス ルールはまだ作成されていないため、外部 IP アドレスを参照すると、NGINX イングレス コントローラーの既定の 404 ページが表示されます。 イングレス ルールは、後続の手順で構成します。

デモ アプリケーションを実行する

動作中のイングレス コントローラーを確認するには、AKS クラスターで 2 つのデモ アプリケーションを実行します。 この例では、kubectl apply を使って、シンプルな kubectl apply アプリケーションのインスタンスを 2 つデプロイします。

aks-helloworld-one.yaml ファイルを作成し、次の例のように YAML にコピーします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: aks-helloworld-one  
spec:
  replicas: 1
  selector:
    matchLabels:
      app: aks-helloworld-one
  template:
    metadata:
      labels:
        app: aks-helloworld-one
    spec:
      containers:
      - name: aks-helloworld-one
        image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
        ports:
        - containerPort: 80
        env:
        - name: TITLE
          value: "Welcome to Azure Kubernetes Service (AKS)"
---
apiVersion: v1
kind: Service
metadata:
  name: aks-helloworld-one  
spec:
  type: ClusterIP
  ports:
  - port: 80
  selector:
    app: aks-helloworld-one

aks-helloworld-two.yaml ファイルを作成し、次の例のように YAML にコピーします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: aks-helloworld-two  
spec:
  replicas: 1
  selector:
    matchLabels:
      app: aks-helloworld-two
  template:
    metadata:
      labels:
        app: aks-helloworld-two
    spec:
      containers:
      - name: aks-helloworld-two
        image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
        ports:
        - containerPort: 80
        env:
        - name: TITLE
          value: "AKS Ingress Demo"
---
apiVersion: v1
kind: Service
metadata:
  name: aks-helloworld-two  
spec:
  type: ClusterIP
  ports:
  - port: 80
  selector:
    app: aks-helloworld-two

kubectl apply を使用して、次の 2 つのデモ アプリケーションを実行します。

kubectl apply -f aks-helloworld-one.yaml --namespace ingress-basic
kubectl apply -f aks-helloworld-two.yaml --namespace ingress-basic

イングレス ルートを作成する

両方のアプリケーションは、Kubernetes クラスターで実行するようになります。 各アプリケーションにトラフィックをルーティングするには、Kubernetes イングレス リソースを作成します。 イングレス リソースでは、2 つのアプリケーションのいずれかにトラフィックをルーティングするルールを構成します。

次の例では、EXTERNAL_IP へのトラフィックが という名前のサービスにルーティングされます。 EXTERNAL_IP/hello-world-two へのトラフィックは、 サービスにルーティングされます。 静的資産の場合、EXTERNAL_IP/static へのトラフィックは という名前のサービスにルーティングされます。

hello-world-ingress.yaml という名前のファイルを作成し、次の例の YAML 内にコピーします。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-world-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - http:
      paths:
      - path: /hello-world-one(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: aks-helloworld-one
            port:
              number: 80
      - path: /hello-world-two(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: aks-helloworld-two
            port:
              number: 80
      - path: /(.*)
        pathType: Prefix
        backend:
          service:
            name: aks-helloworld-one
            port:
              number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-world-ingress-static
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/rewrite-target: /static/$2
spec:
  rules:
  - http:
      paths:
      - path:
        pathType: Prefix
        backend:
          service:
            name: aks-helloworld-one
            port: 
              number: 80
        path: /static(/|$)(.*)

kubectl apply -f hello-world-ingress.yaml コマンドを使用してイングレス リソースを作成します。

$ kubectl apply -f hello-world-ingress.yaml --namespace ingress-basic

ingress.extensions/hello-world-ingress created
ingress.extensions/hello-world-ingress-static created

イングレス コントローラーをテストする

イングレス コント ローラーに対してルートをテストするには、2 つのアプリケーションを参照します。 Web ブラウザーを開き、EXTERNAL_IP などの NGINX イングレス コントローラーの IP アドレスに移動します。 最初のデモ アプリケーションは、次の例で示すように、Web ブラウザーに表示されます。

First app running behind the ingress controller

ここで /hello-world-two パスを IP アドレスに追加し、EXTERNAL_IP/hello-world-two などとします。 カスタム タイトル付きの 2 番目のデモ アプリケーションが表示されます。

Second app running behind the ingress controller

リソースをクリーンアップする

この記事では、Helm を使用して、イングレス コンポーネントおよびサンプル アプリをインストールしました。 Helm グラフをデプロイすると、多数の Kubernetes リソースが作成されます。 これらのリソースには、ポッド、デプロイ、およびサービスが含まれます。 これらのリソースをクリーンアップするには、サンプルの名前空間全体を削除するか、またはリソースを個々に削除します。

サンプルの名前空間とすべてのリソースを削除する

サンプルの名前空間全体を削除するには、kubectl delete コマンドを使用して、名前空間の名前を指定します。 名前空間内のすべてのリソースが削除されます。

kubectl delete namespace ingress-basic

リソースを個々に削除する

作成したリソースを個々に削除するという、きめ細かな方法もあります。 helm list コマンドを使用して、Helm リリースを一覧表示します。 次の出力例に示すように、nginx-ingress および aks-helloworld という名前のグラフを探します。

$ helm list --namespace ingress-basic

NAME                    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                   APP VERSION
nginx-ingress           ingress-basic   1               2020-01-06 19:55:46.358275 -0600 CST    deployed        nginx-ingress-1.27.1    0.26.1  

helm uninstall コマンドを使用してそれらのリリースをアンインストールします。 次の例では、NGINX イングレスのデプロイをアンインストールします。

$ helm uninstall nginx-ingress --namespace ingress-basic

release "nginx-ingress" uninstalled

次に、2 つのサンプル アプリケーションを削除します。

kubectl delete -f aks-helloworld-one.yaml --namespace ingress-basic
kubectl delete -f aks-helloworld-two.yaml --namespace ingress-basic

サンプル アプリにトラフィックを送信していたイングレス ルートを削除します。

kubectl delete -f hello-world-ingress.yaml

最後に、名前空間自体を削除します。 kubectl delete コマンドを使用して、名前空間の名前を指定します。

kubectl delete namespace ingress-basic

次のステップ

この記事には、AKS への外部コンポーネントが含まれています。 これらのコンポーネントの詳細については、次のプロジェクト ページを参照してください。

次のこともできます。