Oracle Cloud Infrastructureドキュメント

例: クラスタでのイングレス・コントローラの設定

Container Engine for Kubernetesで作成したクラスタに、さまざまなオープンソースのイングレス・コントローラを設定できます。

このトピックでは、既存のクラスタ上の対応するアクセス制御とともに、イングレス・コントローラの例を設定する方法について説明します。 イングレス・コントローラを設定すると、このトピックでは、イングレス・コントローラをhello-worldバックエンドの例とともに使用する方法、およびイングレス・コントローラが想定どおりに機能していることを検証する方法について説明します。

コンポーネント例

この例には、イングレス・コントローラとhello-worldバックエンドが含まれます。

イングレス・コントローラ・コンポーネント

イングレス・コントローラは次の構成で構成されます:

  • イングレス・コントローラ・デプロイメントをnginx-ingress-controllerと呼びます。 デプロイメントによって、イングレス・コントローラとNginx用のバイナリを含むイメージがデプロイされます。 Kubernetesでイングレスが作成されると、バイナリ操作により/etc/nginx/nginx.conf構成ファイルがリロードされます。 Nginxのアップストリームは、指定されたセレクタに一致するサービスを指します。
  • ingress-nginxと呼ばれるイングレス・コントローラ・サービス。 このサービスは、イングレス・コントローラのデプロイメントをLoadBalancerタイプのサービスとして公開します。 Container Engine for KubernetesOracle Cloud Infrastructure統合/クラウド・プロバイダを使用するため、正しいノードをバックエンド・セットとして構成してロード・バランサを動的に作成します。

バックエンド・コンポーネント

実際のバックエンドは次のように構成されています:

  • バックエンド・デプロイメント(docker-hello-world)。 デプロイメントでは、ヘルス・チェックおよび404レスポンスのデフォルト・ルートが処理されます。 これは、デフォルト・バックエンドに必要な最小ルートを提供するストック・シェルの未処理イメージを使用して行われます。
  • docker-hello-world-svcというバックエンド・サービスは、イングレス・コントローラのデプロイメントによって、バックエンド・デプロイメントで使用されるものを公開します。

サンプル・イングレス・コントローラの設定例

このセクションでは、イングレス用のアクセス・ルールを作成します。 次に、イングレス・コントローラ・コンポーネントの例を作成し、実行中であることを確認します。

イングレス・コントローラのアクセス・ルールの作成

  1. まだ行っていない場合は、cluster kubeconfig構成ファイルをダウンロードし、そのファイルを指すようにKUBECONFIG環境変数を設定します。 「クラスタ・アクセスを有効にするためのkubeconfigファイルのダウンロード」を参照してください。
  2. 端末ウィンドウで、次のように入力して、ユーザーにKubernetes RBAC cluster-admin clusterroleを付与します:

    $ kubectl create clusterrolebinding <my-cluster-admin-binding> --clusterrole=cluster-admin --user=<user_OCID>

    説明:

    • <my-cluster-admin-binding>は、ユーザーとKubernetes RBAC cluster-admin clusterroleとの間のバインディングの名前として使用する選択した文字列です。 たとえば、jdoe_clst_adm
    • <user_OCID>は、ユーザーOCID (コンソールから取得)です。 たとえば、ocid1.user.oc1..aaaaa...zutq (読みやすくするために省略)。

    例えば:

    $ kubectl create clusterrolebinding jdoe_clst_adm --clusterrole=cluster-admin --user=ocid1.user.oc1..aaaaa...zutq

サービス・アカウントとイングレス・コントローラの作成

  1. 次のコマンドを実行して、nginx-ingress-controllerイングレス・コントローラのデプロイメントを、Kubernetes RBACのロールおよびバインディングとともに作成します:

    $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
  2. 次のコードを含むファイルcloud-generic.yamlを作成して保存し、ingress-nginxイングレス・コントローラ・サービスをロード・バランサ・サービスとして定義します:

    kind: Service
    apiVersion: v1
    metadata:
      name: ingress-nginx
      namespace: ingress-nginx
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
    spec:
      type: LoadBalancer
      selector:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
      ports:
        - name: http
          port: 80
          targetPort: http
        - name: https
          port: 443
          targetPort: https
  3. 保存したファイルを使用し、次のコマンドを実行して、ingress-nginxイングレス・コントローラ・サービスを作成します:

    $ kubectl apply -f cloud-generic.yaml

ingress-nginxイングレス・コントローラ・サービスがロード・バランサ・サービスとして実行中であることの確認

  1. 実行中のサービスの一覧を表示する:

    $ kubectl get svc -n ingress-nginx
    
    NAME            TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)                       AGE
    ingress-nginx   LoadBalancer   10.96.229.38   <pending>      80:30756/TCP,443:30118/TCP    1h
    

    ingress-nginxイングレス・コントローラ・サービスのEXTERNAL-IPは、ロード・バランサがOracle Cloud Infrastructureで完全に作成されるまで、<pending>として表示されます。

  2. ingress-nginxイングレス・コントローラ・サービスに対してEXTERNAL-IPが表示されるまで、kubectl get svcコマンドを繰り返します:

    $ kubectl get svc -n ingress-nginx
    
    NAME            TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)                       AGE
    ingress-nginx   LoadBalancer   10.96.229.38   129.146.214.219   80:30756/TCP,443:30118/TCP    1h
    		

TLSシークレットの作成

TLS秘密は、イングレス・コントローラのSSL終了に使用されます。 この例のシークレットを生成するには、自己署名証明書が使用されます。 これはテストでは問題ありませんが、本番用の場合は、認証局が署名した証明書を使用してください。

$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
			
$ kubectl create secret tls tls-secret --key tls.key --cert tls.crt

ノート

Windowsでは、"/CN=nginxsvc/O=nginxsvc""//CN=nginxsvc\O=nginxsvc"に置き換える必要があります。
たとえば、Git Bashシェルからopensslコマンドを実行する場合は、これが必要です。

サンプル・バックエンドの設定

この項では、シェルのないバックエンド・サービスとデプロイメントを定義します。

docker-hello-worldサービス定義の作成

  1. 次のコードを含むファイルhello-world-ingress.yamlを作成します。 このコードは、Docker Hubから提供されている未処理のイメージを使用します。 同様の方法で実行できる、選択した別のイメージに置き換えることができます。

    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
      name: docker-hello-world
      labels:
        app: docker-hello-world
    spec:
      replicas: 3
      template:
        metadata:
          labels:
            app: docker-hello-world
        spec:
          containers:
          - name: docker-hello-world
            image: scottsbaldwin/docker-hello-world:latest
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: docker-hello-world-svc
    spec:
      selector:
        app: docker-hello-world
      ports:
        - port: 8088
          targetPort: 80
      type: ClusterIP
    

    ドッキングしていないサービス・タイプは、LoadBalancerではなくClusterIPです。このサービスは、ingress-nginxイングレス・コントローラ・サービスによってプロキシ設定されるためです。 docker-hello-worldサービスは、直接公開アクセスする必要はありません。 代わりに、パブリック・アクセスはロード・バランサからイングレス・コントローラに、イングレス・コントローラからアップストリーム・サービスにルーティングされます。

  2. 次のコマンドを実行して、クラスタ内のノード上に新しいシェルのデプロイメントとサービスを作成します:

    $ kubectl create -f hello-world-ingress.yaml
    

サンプル・イングレス・コントローラを使用したサンプル・バックエンドへのアクセス

このセクションでは、イングレス・コントローラを使用してバックエンドにアクセスするための追跡を作成します。

イングレス・リソースの作成

  1. ingress.yamlファイルを作成し、次のコードをイングレスします:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: hello-world-ing
      annotations:
        kubernetes.io/ingress.class: "nginx"
    spec:
      tls:
      - secretName: tls-secret
      rules:
      - http:
          paths:
          - backend:
              serviceName: docker-hello-world-svc
              servicePort: 8088
    
  2. リソースを作成します:

    $ kubectl create -f ingress.yaml
    

サンプル・コンポーネントが想定どおりに機能していることの確認

このセクションでは、サンプル・コンポーネントのすべてが正常に作成され、期待どおりに動作していることを確認します。 docker-hello-world-svcサービスはClusterIPサービスとして実行する必要があり、ingress-nginxサービスはLoadBalancerサービスとして実行する必要があります。 イングレス・コントローラに送信されたリクエストは、クラスタ内のノードにルーティングする必要があります。

ロード・バランサの外部IPアドレスの取得

ingress-nginxサービスがLoadBalancerサービスとして実行されていることを確認するには、その外部IPアドレスを取得します:

$ kubectl get svc --all-namespaces
			
NAMESPACE       NAME                     TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)                      AGE
default         docker-hello-world-svc   ClusterIP      10.96.83.247    <none>           8088/TCP                     16s
default         kubernetes               ClusterIP      10.96.0.1       <none>           443/TCP                      1h
ingress-nginx   ingress-nginx            LoadBalancer   10.96.229.38    129.146.214.219  80:30756/TCP,443:30118/TCP   5m			
kube-system     kube-dns                 ClusterIP      10.96.5.5       <none>           53/UDP,53/TCP                1h
kube-system     kubernetes-dashboard     ClusterIP      10.96.208.64    <none>           443/TCP                      1h
kube-system     tiller-deploy            ClusterIP      10.96.28.102    <none>           44134/TCP                    1h

ロード・バランサへのcURLリクエストの送信

  1. ingress-nginxサービスの外部IPアドレス(たとえば、129.146.214.219)を使用してHTTPリクエストをカールします:

    $ curl -I http://129.146.214.219
    
    HTTP/1.1 301 Moved Permanently
    Via: 1.1 10.68.69.10 (McAfee Web Gateway 7.6.2.10.0.23236)
    Date: Thu, 07 Sep 2017 15:20:16 GMT
    Server: nginx/1.13.2
    Location: https://129.146.214.219/
    Content-Type: text/html
    Content-Length: 185
    Proxy-Connection: Keep-Alive
    Strict-Transport-Security: max-age=15724800; includeSubDomains;
    

    出力には、httpトラフィックがhttpsにリダイレクトされていることを示す301リダイレクトとLocationヘッダーが表示されます。

  2. https urlに対してcURLを指定するか、-Lオプションを追加して、ロケーションのヘッダーに自動的に従います。 -kオプションは、SSL証明書を検証しないようにcURLに指示します。

    $ curl -ikL http://129.146.214.219
    
    HTTP/1.1 301 Moved Permanently
    Via: 1.1 10.68.69.10 (McAfee Web Gateway 7.6.2.10.0.23236)
    Date: Thu, 07 Sep 2017 15:22:29 GMT
    Server: nginx/1.13.2
    Location: https://129.146.214.219/
    Content-Type: text/html
    Content-Length: 185
    Proxy-Connection: Keep-Alive
    Strict-Transport-Security: max-age=15724800; includeSubDomains;
    
    HTTP/1.0 200 Connection established
    
    HTTP/1.1 200 OK
    Server: nginx/1.13.2
    Date: Thu, 07 Sep 2017 15:22:30 GMT
    Content-Type: text/html
    Content-Length: 71
    Connection: keep-alive
    Last-Modified: Thu, 07 Sep 2017 15:17:24 GMT
    ETag: "59b16304-47"
    Accept-Ranges: bytes
    Strict-Transport-Security: max-age=15724800; includeSubDomains;
    
    <h1>Hello webhook world from: docker-hello-world-1732906117-0ztkm</h1>
    

    出力の最後の行は、ホスト名がdocker-hello-world-1732906117-0ztkmであるポッドから返されたHTMLを示しています

  3. cURLリクエストを複数回発行して、ロード・バランシングが発生していることを示すHTML出力の変更でホスト名を確認します:

    $ curl -k https://129.146.214.219
    
    <h1>Hello webhook world from: docker-hello-world-1732906117-6115l</h1>
    
    $ curl -k https://129.146.214.219
    
    <h1>Hello webhook world from: docker-hello-world-1732906117-7r89v</h1>
    
    $ curl -k https://129.146.214.219
    
    <h1>Hello webhook world from: docker-hello-world-1732906117-0ztkm</h1>
    

nginx.confの検査

nginx-ingress-controllerイングレス・コントローラのデプロイメントは、実行中のpod内のnginx.confファイルを操作します。

  1. nginx-ingress-controllerイングレス・コントローラのデプロイメントを実行しているポッドの名前を見つけ、それをkubectl execコマンドとともに使用して、nginx.confの内容を表示します。

    $ kubectl get po -n ingress-nginx
    			
    NAME                                       READY     STATUS    RESTARTS   AGE
    nginx-ingress-controller-110676328-h86xg   1/1       Running   0          1h
    
    $ kubectl exec -n ingress-nginx -it nginx-ingress-controller-110676328-h86xg -- cat /etc/nginx/nginx.conf
    
  2. 出力でproxy_passを探します。 デフォルトのバックエンド用のものと、次のようなものがあります:

    proxy_pass http://upstream_balancer;
    

    これは、Nginxがupstream_balancerという上流へのプロキシ・リクエストであることを示しています。

  3. 出力で上流の定義を見つけます。 次のようになります:

    upstream upstream_balancer { server 0.0.0.1:1234; # placeholder balancer_by_lua_block { tcp_udp_balancer.balance() } }

    アップストリームは、Luaを介してプロキシ設定されています。