はじめに
この連載ではコンテナオーケストレーションツールである、 Kubernatesの使い方を学びます。
今回はIngressについて学習します。
サンプルコード
こちらに順次アップしていきますー。
連載記事一覧
Ingress
NodePortを使用すればKubernetesクラスタ外にServiceを公開することができます。
ただし、この手法はあくまでもL4層レベルまでしか扱えないため、パスベースで転送先のServiceを切り替えるといったL7層レベルの制御はできません。
Ingressを使用すれば、ServiceのKubernetesクラスタの外への公開と、VirtualHostやパスベースでの高度なHTTPルーティングを両立します。
しかし、通常のローカルKubernetes環境ではIngressを使ったServiceの公開をすることはできません。
クラスタの外からのHTTPリクエストをServiceにルーティングするためのnginx_ingress_controllerを次のようにデプロイします。
$ kubectl apply -f \ https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.16.2/deploy/mandatory.yaml $ kubectl apply -f \ https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.16.2/deploy/provider/cloud-generic.yaml
ingress-nginxというNamespace上に次のようなServiceとPodが作成されます.
$ kubectl -n ingress-nginx get service,pod NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/default-http-backend ClusterIP 10.100.224.213 <none> 80/TCP 54s service/ingress-nginx LoadBalancer 10.99.9.129 localhost 80:31361/TCP,443:30547/TCP 28s NAME READY STATUS RESTARTS AGE pod/default-http-backend-55b84578bf-pszn2 1/1 Running 0 53s pod/nginx-ingress-controller-b5d545f8f-v5dmw 1/1 Running 0 54s
Ingressを通じたアクセス
実際にIngressを通してServiceにアクセスしてみましょう。simple-service-ingress.yamlを次のように定義します。spec.typeが未指定のときはClusterIP Serviceで作成されます。
# simple-service-ingress.yaml apiVersion: v1 kind: Service metadata: name: echo spec: selector: app: echo ports: - name: http port: 80
マニフェストファイルの変更を反映します。
$ kubectl apply -f simple-service-ingress.yaml
Ingressを定義したマニフェストファイルsimple-ingress.yamlを作成・反映します。
# simple-ingress.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: echo spec: rules: - host: ch05.gihyo.local http: paths: - path: / backend: serviceName: echo servicePort: 80
$ kubectl apply -f simple-ingress.yaml ingress.extensions/echo created $ kubectl get ingress NAME HOSTS ADDRESS PORTS AGE echo ch05.gihyo.local localhost 80 7s
IngressはL7層のルーティングが可能なので、指定したホストやパスに合致したサービスにリクエストを委譲できます。
ローカルから次のようにHTTPリクエストを投げるとバックエンドに存在するecho Serviceから次のようにレスポンスが返ってきます。
$ curl http://localhost -H 'Host: ch05.gihyo.local' Hello Docker!!
他にもHTTPリクエストをIngressの層で様々な制御をすることができます。例えば、simple-ingress.yamlに次のような変更を加えます。
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: echo annotations: nginx.ingress.kubernetes.io/server-snippet: | set $agentflag 0; if ($http_user_agent ~* "(Mobile)" ){ set $agentflag 1; } if ( $agentflag = 1 ) { return 301 http://gihyo.jp/; } spec: rules: - host: ch05.gihyo.local http: paths: - path: / backend: serviceName: echo servicePort: 80
では反映してみます
$ kubectl apply -f simple-ingress.yaml ingress.extensions/echo configured
では実際にアクセスしてみます。ここでは、User-AgentにMobileが含まれているリクエストを別のURLにリダイレクトしています。simple-ingress.yamlを反映し、User-AgentにMobileをリクエストを発行すると、301でリダイレクトされることがわかります。
$ curl -LI http://localhost \ -H 'Host: ch05.gihyo.local' \ -H 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X)a AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1'
IngressでHTTPリクエストの制御ができるため、バックエンドのWebサーバやアプリケーション側ではこのような処理を入れる必要はなくなります。
nginx-ingress-controllerでは他にも様々な機能があります。
IngressはパブリッククラウドにおいてはそのプラットフォームのL7ロードバランサーを利用できます。GCPの場合はデフォルトでCloud Load Balancingを、AWSであればApplication Load Balancerを利用可能です。
まとめ
ここまでローカルKubernetes環境を利用してKubernetesの基本的な概念や操作を体験してきました。しかし、ローカルKubernetes環境ではKubernetesの全ての機能を備えてるわけではないためできることには限界があります。
次回以降ではパブリッククラウドを用いたより実践的なKubernetesでのアプリケーション構築、オンプレミスでのKubernetesクラスタの構築を紹介していきます。