deis-routerなしでKubernetesのIngressでDeisを動かす

Clusterを作る時にデフォルトでついてくるLBを外す

gloucd container clusters createをするときに、--disable-addons "HttpLoadBalancing"をつける。これをしないとGLBCがIngress Controllerとなってしまうため。コマンドラインからしか外せない。

cluster作成後どうなってるか

このときはkube-systemのnamesapce配下にkubernetesが動くために必要なものが起動されてる。addonを外したので、l7-default-backendなどは存在しない。

フラグ付きでDeisをインストール

$ helm install deis/workflow --namespace deis \
 --set global.experimental_native_ingress=true \
 --set controller.platform_domain=example.com

global.experimental_native_ingress=trueがポイント。

deis/routerの代わりにingressが作成されている。

$ kd describe ing
Name:           controller-api-server-ingress-http
Namespace:      deis
Address:
Default backend:    default-http-backend:80 (<none>)
Rules:
  Host              Path    Backends
  ----              ----    --------
  deis.example.com
                    /   deis-controller:80 (<none>)
Annotations:
Events: <none>

この段階でGCP側にこの辺が追加になる。

Ingress Controllerをインストール

今は、addonで外しているのでIngress Controllerがkubernetes上にいない状態。helmコマンドでIngress controllerをインストールする。今回は、treafikというLBのソフトウェアを利用する。

$ helm install stable/traefik --name deis-ingress-001 --namespace kube-system

これをすると

  • GCP上に80,443のHTTPを通すFirewallが作られ
  • TCP:80,443のL4ロードバランサーが作られ
  • treafikのimageがdeployされてそのL4 LBと結びつく

あとは、このとき作成されたLBのExternal IPとdeis.example.comをひけるAレコードを作成する。

Deisでアプリケーションをdeploy

通常通りregisterして、アプリケーションをdeployしたりすると以下のような動きをしてルーティングが行われる。

  • アプリケーションのnamespaceが追加
  • 該当のnamespaceにアプリケーションのdeploymentが追加
  • 該当のnamespaceにClusterIP型のserviceが追加
  • 該当のnamespaceにIngressも追加されて、そのClusterIP型のserviceを向く
     internet
        |
     [ LB ]
        |
   [ Traefik ]
   ____|____________________
  |                        |
[ deis/controller   ]     [ App ]

cluster作成時に作られるaddonのGLBCでやってみたが

これがうまくいかなかった。 まず、さっきと同じようにhelm installしたあとのFirewallとIngressの状態がちょっと違う。 まず、FirewallはGCP内のロードバランサーたちが所属するCIDRから、Nodeへの特定TCPポートを開くルールが作られる。これはhealthcheck用のようだ。

で、Ingressはdeis-controllerサービスが見つかりませんよーというエラーが出てくる。

$ kd describe ing
Name:           controller-api-server-ingress-http
Namespace:      deis
Address:        130.211.37.103
Default backend:    default-http-backend:80 (10.0.2.3:8080)
Rules:
  Host              Path    Backends
  ----              ----    --------
  deis.example.com
                    /   deis-controller:80 (<none>)
Annotations:
  forwarding-rule:  k8s-fw-deis-controller-api-server-ingress-http--90b3b4269724c70
  target-proxy:     k8s-tp-deis-controller-api-server-ingress-http--90b3b4269724c70
  url-map:      k8s-um-deis-controller-api-server-ingress-http--90b3b4269724c70
  backends:     {"k8s-be-31752--90b3b4269724c7ab":"Unknown"}
Events:
  FirstSeen LastSeen    Count   From            SubObjectPath   Type        Reason  Message
  --------- --------    -----   ----            -------------   --------    ------  -------
  3m        3m      1   loadbalancer-controller         Normal      ADD deis/controller-api-server-ingress-http
  2m        2m      1   loadbalancer-controller         Normal      CREATE  ip: 130.211.37.103
  2m        2m      3   loadbalancer-controller         Warning     Service Could not find nodeport for backend {ServiceName:deis-controller ServicePort:{Type:0 IntVal:80 StrVal:}}: Could not find matching nodeport from service.
  2m        2m      3   loadbalancer-controller         Normal      Service no user specified default backend, using system default

deis-controllerはtype:ClusterIPというクラスター内部IPのみで接続できるサービスとして公開されるようになってるが、このClusterIPとIngressとGLBCだと相性が悪く接続に失敗するようだった。ドキュメントにちゃんと書いとけよ的なissueもあがってた。

なので、現状は、GLBCをIngress ControllerとしたGKE上ではNative Ingressの利用は難しそうだった。。

まとめ

やってみるとまだ対応されてない(grafanaとかのルーティングがない)ところがあって、フラグについてるExperimentalは伊達じゃないと感じた。なので、やっぱりdeis/routerを使う方法にすることにした。