Ingressのチュートリアル
    • PDF

    Ingressのチュートリアル

    • PDF

    Article Summary

    Classic環境で利用できます。

    Ingressは、Cluster外部のリクエストをIngressリソースに定義されたルールに従って、Cluster内部のサービスに接続します。
    より詳しい説明は、KubernetesのIngress文書をご参照ください。
    このガイドでは、URIによるルーティングとホストによるルーティング、この2つの方法を設定してみます。

    準備事項

    • 運用中のClusterとkubectlのインストール及び環境変数の設定が必要です。
      • Clusterを作る際、インストールモジュールでIngress Nginxを選択して作られた場合、Ingress ControllerServiceとが自動的に作られるため、以下のEXTERNAL-IP確認するからお進めください。
    • Clusterの作成は、Clusterを作成するをご参照ください。
    • kubectlのインストール及び環境変数の設定は、 kubectlをインストールするをご参照ください。

    Ingress Controllerを配布する

    以下のコマンドを行うと、ingress-nginxというNamespaceが作成され、Ingressの実現体であるingress-nginxに必要なリソースが作られます。

    kubectl --kubeconfig $KUBE_CONFIG apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/2de5a893aa15f14102d714e918b0045b960ad1a5/deploy/static/mandatory.yaml
    
    • 実行結果
    namespace/ingress-nginx created
    configmap/nginx-configuration created
    configmap/tcp-services created
    configmap/udp-services created
    serviceaccount/nginx-ingress-serviceaccount created
    Clusterrole.rbac.authorization.k8s.io/nginx-ingress-Clusterrole created
    role.rbac.authorization.k8s.io/nginx-ingress-role created
    rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
    Clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-Clusterrole-nisa-binding created
    deployment.apps/nginx-ingress-controller created
    

    Ingress Serviceを作る

    外部からアクセスすることができるように、LoadBalancerタイプのIngress Serviceを作ります。

    kubectl --kubeconfig $KUBE_CONFIG apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/2de5a893aa15f14102d714e918b0045b960ad1a5/deploy/static/provider/cloud-generic.yaml
    
    • 実行結果
    service/ingress-nginx created
    

    ロードバランサーの作成有無をリアルタイムで確認する

    kubectl --kubeconfig $KUBE_CONFIG get service -n ingress-nginx --watch
    
    • 実行結果
    NAME            TYPE           Cluster-IP      EXTERNAL-IP   PORT(S)                      AGE
    ingress-nginx   LoadBalancer   172.17.116.11   <pending>     80:31583/TCP,443:32586/TCP   4s
    ingress-nginx   LoadBalancer   172.17.116.11   slb-1976810.n...   80:31583/TCP,443:32586/TCP   27s
    

    EXTERNAL-IPを確認する

    Serviceがpending状態で作成が完了すると、EXTERNAL-IPを確認します。

    kubectl --kubeconfig $KUBE_CONFIG get service -n ingress-nginx
    
    • 実行結果
    NAME            TYPE           Cluster-IP      EXTERNAL-IP                 PORT(S)                      AGE
    ingress-nginx   LoadBalancer   172.17.116.11   slb-1976810.ncloudslb.com   80:31583/TCP,443:32586/TCP   59s
    

    Application及びサービスの配布

    それぞれ異なる情報をもつ2つの例題用のDeployment及びServiceを作ります。例題用のDeploymentは、自分のホスト情報を示すdemo用のnginx containerであり、各Serviceは、ClusterIPタイプで作られ、外部から直接アクセスができない状態です。

    kubectl --kubeconfig $KUBE_CONFIG apply -f https://gist.githubusercontent.com/NaverCloudPlatformDeveloper/c47620d8d25b2a0e08648f225043adf6/raw/675addde0a56ba727824f30f92a73b40550fb73c/nks-tutorial-hello-service.yaml
    
    • 実行結果
    deployment.apps/a created
    service/a-svc created
    deployment.apps/b created
    service/b-svc created
    

    URIベースのルーティング

    上記で作ったIngress ServiceのExternal IPの最後に付くPath別にルーティングを行い、/aでリクエストする時と、/bでリクエストする時にそれぞれ異なるサービスで接続されるように設定してみます。

    Ingressを作る

    例題のIngressリソースは、以下のように、各pathに応じてbackendを相違に設定し、/aでアクセスする場合はa-svcで、/bでアクセスする場合はb-svcで、アクセスするように設定しました。

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: ab-ingress
      annotations:
        kubernetes.io/ingress.class: nginx
        ingress.kubernetes.io/rewrite-target: /
        nginx.ingress.kubernetes.io/ssl-redirect: "false"
    spec:
      rules:
      - http:
          paths:
          - path: /a
            backend:
              serviceName: a-svc
              servicePort: 80
          - path: /b
            backend:
              serviceName: b-svc
              servicePort: 80
    

    以下のコマンドでIngressを作ります。

    kubectl --kubeconfig $KUBE_CONFIG apply -f https://gist.githubusercontent.com/NaverCloudPlatformDeveloper/eca9d12336e008f1c7102892750aeae5/raw/3f3d0916d89161a1d81ed19464b9991154a8b9f8/nks-tutorial-ab-ingress.yaml
    
    • 実行結果
    ingress.extensions/ab-ingress created
    
    参考

    例では、TLS設定を行っていないため、強制のredirectionを防ぐために、ingress annotationにnginx.ingress.kubernetes.io/ssl-redirect: "false"を追加したが、TLSの設定の際に当該annotationを削除してください。

    Ingressの作成を確認する

    kubectl get ingressコマンドで作成されたingressを確認することができます。

    kubectl --kubeconfig $KUBE_CONFIG get ingress
    
    • 実行結果
    NAME         HOSTS   ADDRESS                     PORTS   AGE
    ab-ingress   *       slb-1976810.ncloudslb.com   80      19s
    

    サービス接続を確認する

    ブラウザ又はcurlを通じて接続の結果を確認すると、それぞれ異なるServiceのPodでアクセスすることを確認することができます。

    例示

    • http://slb-1976810.ncloudslb.com/a
    $ curl http://slb-1976810.ncloudslb.com/a
    Server address: 172.24.21.10:80
    Server name: a-57598bbddd-9hcc6
    Date: 09/Jul/2019:09:03:36 +0000
    URI: /a
    Request ID: add732582fb99d0cfffe3edc83169517
    
    • http://slb-1976810.ncloudslb.com/b
    $ curl http://slb-1976810.ncloudslb.com/b
    Server address: 172.24.21.11:80
    Server name: b-657f4794f4-k48hb
    Date: 09/Jul/2019:09:03:37 +0000
    URI: /b
    Request ID: 6cfd25c99f677c75ad815eaf57fc24c5
    

    ホストベースのルーティング

    今回は、同じEXTERNAL-IPに対してそれぞれ異なるドメインでリクエストする際、異なるサービスで接続されるように設定してみます。

    従来のingressを削除する

    上記で作ったab-ingressを削除します。

    kubectl --kubeconfig $KUBE_CONFIG delete ingress ab-ingress
    
    • 実行結果
    ingress.extensions "ab-ingress" deleted
    

    Ingressを作成する

    以下の例は、a.svc.comでリクエストする場合はa-svcで、b.svc.comでリクエストする場合はb-svcで接続するように、それぞれの hostによってbackendを異ならせています。

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: ab-host-ingress
      annotations:
        kubernetes.io/ingress.class: nginx
        ingress.kubernetes.io/rewrite-target: /
    spec:
      rules:
      - host: a.svc.com
        http:
          paths:
          - path: /
            backend:
              serviceName: a-svc
              servicePort: 80
      - host: b.svc.com
        http:
          paths:
          - path: /
            backend:
              serviceName: b-svc
              servicePort: 80
    

    以下のコマンドでIngressを作成します。

    kubectl --kubeconfig $KUBE_CONFIG apply -f https://gist.githubusercontent.com/NaverCloudPlatformDeveloper/39913ee1025c45aaa0d50753db8a7555/raw/91082b01c0f26313b0a11e61df8984ac6c6b5c46/nks-tutorial-ab-host-ingress.yaml
    
    • 実行結果
    ingress.extensions/ab-host-ingress created
    

    Ingressの作成を確認する

    kubectl get ingressコマンドで作成されたingressを確認することができ、HOSTSa.svc.comb.svc.comがあることを確認することができます。

    kubectl --kubeconfig $KUBE_CONFIG get ingress
    
    • 実行結果
    NAME              HOSTS                 ADDRESS                     PORTS   AGE
    ab-host-ingress   a.svc.com,b.svc.com   slb-1976810.ncloudslb.com   80      3m57s
    

    サービス接続を確認する

    例題のホストに設定したドメインは実際にはないドメインであるため、curlコマンドに-H hostオプションを入れてホスト別の接続の際に異なるサービスが表示されるか確認します。

    例示

    • a.svc.com
    $ curl -H host:a.svc.com http://slb-1976810.ncloudslb.com
    Server address: 172.24.21.10:80
    Server name: a-57598bbddd-9hcc6
    Date: 09/Jul/2019:08:33:03 +0000
    URI: /
    Request ID: b340711ab142bef67fdb07e7fd077ddb
    
    • b.svc.com
    $ curl -H host:b.svc.com http://slb-1976810.ncloudslb.com
    Server address: 172.24.21.11:80
    Server name: b-657f4794f4-k48hb
    Date: 09/Jul/2019:08:33:12 +0000
    URI: /
    Request ID: eb6a876acbb2db7155ff26992b6635e4
    

    参考事項

    名前に_(underscore)のあるRequest Headerは、サーバから確認できません。

    ingress-nginxでは、request header名に_(underscore)入れば強制削除します。それを回避するためには、ConfigMapにenable-underscores-in-headers: trueを追加する必要があります。詳しい内容は、ingress-nginxのConfigMaps文書をご参照ください。

    サーバからRequestのClient IPを確認すると、Cluster内部のIPとして表示されます。

    ingress-nginxを利用し、ClientのReal IPを完全に取得するためには、LoadBalancerのproxy protocolの設定と、ingress-nginxのuse-proxy-protocol: true ConfigMapが設定されている必要があります。
    LoadBalancerのproxy protocolの有効化は、Kubernetesのサービスを通じたロードバランサーとの連携をご参考にしていただき、
    ingress-nginxのConfigMapの設定は、ingress-nginxのConfigMaps文書をご参照ください。

    Load Balancerでingress-nginx PodのないNodeはHealth Checkに失敗したと表示されます。

    上記の例示で、ingress-nginx Serviceを作る場合、Service .spec.externalTrafficPolicy: Localに設定されていることを確認することができます。

    .spec.externalTrafficPolicyは、サービスで外部のトラフィックをどのようにルーティングするかを設定することができます。使用可能な値は、Cluster(default)とLocalです。

    • Cluster:外部トラフィックを全Podに分散します。別のNodeにあるPodで転送する際、2番目のホップを引き起こす可能性があるが、Podへのトラフィックはバランスよく分散することができます。
    • Local:外部トラフィックをローカルNodeにあるPodのみで転送します。別のNodeに対する2番目のホップは避けることができるが、不均衡なトラフィックの分散が発生する可能性があります。

    ingress-nginx Serviceの.spec.externalTrafficPolicy: Localになっている場合、ingress-nginx Podが動作中のNodeのみにトラフィックが転送されるため、その他のサーバはHealth Checkに失敗したと表示されます。

    動作に関する詳しい内容は、Kubernetesの文書にて確認することができ、各サービスに合った設定に変更することをお勧めいたします。


    この記事は役に立ちましたか?

    Changing your password will log you out immediately. Use the new password to log back in.
    First name must have atleast 2 characters. Numbers and special characters are not allowed.
    Last name must have atleast 1 characters. Numbers and special characters are not allowed.
    Enter a valid email
    Enter a valid password
    Your profile has been successfully updated.