Docker/Kubernetes 実践コンテナ開発入門@26日目

Docker/Kubernetes 実践コンテナ開発入門:書籍案内|技術評論社

前回は、k8s のリソースの Service について学習しました。 Service は基本的には Pod→Pod への経路を指定するためのものでした。

今回は Ingress についてやっていきます。

5.10 Ingress

  • NodePort は L4 層レベルまでのため、HTTP/HTTPS のように L7 層レベルの制御ができない

  • これを解決するのが Ingress

  • 素のローカル k8s 環境では使えない。

  • そのため、nginx_ingress_controller をデプロイします。

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.16.2/deploy/mandatory.yaml
namespace/ingress-nginx created
service/default-http-backend 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
unable to recognize "https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.16.2/deploy/mandatory.yaml": no matches for kind "Deployment" in version "extensions/v1beta1"
unable to recognize "https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.16.2/deploy/mandatory.yaml": no matches for kind "Deployment" in version "extensions/v1beta1"

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.16.2/deploy/provider/cloud-generic.yaml
service/ingress-nginx created
$  kubectl api-resources | grep deployment
deployments                       deploy       apps                           true         Deployment
$ kubectl apply -f mandatory.yaml
namespace/ingress-nginx created
deployment.apps/default-http-backend created
service/default-http-backend 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
  • さっきは Pod が起動してなかったけど、ちゃんと Pod も起動してくれた
  • これで Ingress リソースを利用する準備が整った
$ kubectl -n ingress-nginx get service,pod
NAME                           TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
service/default-http-backend   ClusterIP      10.108.154.236   <none>        80/TCP                       93s
service/ingress-nginx          LoadBalancer   10.104.144.30    localhost     80:30719/TCP,443:31795/TCP   11s

NAME                                           READY   STATUS    RESTARTS   AGE
pod/default-http-backend-57fb4c77b4-zxq6b      1/1     Running   0          93s
pod/nginx-ingress-controller-7bfbcc484-ql2m8   1/1     Running   0          93s

5.10.1 Ingress を通じたアクセス

  • Ingress を通して Service にアクセス

  • simple-service.yaml

    • spec.type が未指定のときは ClusterIP Service で作成される
apiVersion: v1
kind: Service
metadata:
  name: echo
spec:
  selector:
    app: echo
  ports:
    - name: http
      port: 80
  • マニフェストファイルの変更を反映
$ kubectl apply -f simple-service.yaml
The Service "echo" is invalid: spec.ports[0].nodePort: Forbidden: may not be used when `type` is 'ClusterIP'
  • エラーが出るので一旦 Service 削除
$ kubectl delete -f simple-service.yaml
service "echo" deleted
  • 再度実行
$ kubectl apply -f simple-service.yaml
service/echo created
  • 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   CLASS    HOSTS              ADDRESS     PORTS   AGE
echo   <none>   ch05.gihyo.local   localhost   80      42s
  • Ingeress の spec.rules.host 属性に合致するのでバックエンドの Service にリクエストが委譲されるようだ。
$ curl http://localhost -H 'Host: ch05.gihyo.local'
Hello Docker!!
  • 他にも 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
  • モバイルに偽装してリクエストを飛ばすとリダイレクトされることがわかる。
$ curl http://localhost -H 'Host: ch05.gihyo.local' -H 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1'
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.13.12</center>
</body>$ curl http://localhost -H 'Host: ch05.gihyo.local' -H 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1'
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.13.12</center>
</body>
  • バックエンドの Web サーバやアプリケーションがこのような制御から解放される
  • Ingress はパブリッククラウドにおいてはそのプラットフォームの L7 ロードバランサーを利用可能
    • GCP
      • Cloud Load Balancing
    • AWS
      • Application Load Balancer

コラム freshpod でイメージの更新を検知し,Pod を自動更新する

  • freshpod
    • イメージの更新を検知し、Pod を自動更新する
    • webpacker の dev-server とかに近いイメージを持った!

コラム kube-prompt

  • kube-prompt
    • macOS/Linux 向け
    • kubectl のコマンドや、リソース名の候補を補完してくれるツール

コラム Kubernetes API

  • k8s のリソースの作成・更新・削除は k8s クラスタにデプロイされている API によって実行される
  • apiVersion はリソースの操作に利用する API の種別
  • k8s クラスタで利用できる API の確認方法
$ kubectl api-versions
  • 各種リソースがどの API に対応しているかはリポジトリを見る。
  • v1
    • Service、Pod
  • apps/v1
    • Deployment
  • extenxionx/v1beta1
    • Ingress

今日の学び

  • Ingress は外部からの HTTP/HTTPS リクエストを受けることができ、Service に委譲することができる。
  • 設定次第では、Web サーバやアプリケーション層の L7 層の役割を担うことができる。
  • 最初はテキスト通りにうまくいかずどうなるかと思ったけど、なんとか動いてくれてよかった!
Hugo で構築されています。
テーマ StackJimmy によって設計されています。