まーぽんって誰がつけたの?

iOS→Scala→インフラなおじさん技術メモ

kopsを使ってAWS上にkubernetesを構築したときにIngress Controllerはどれにしようか悩んでいる

GKEで甘えてきました

www.mpon.me

今まではGKE使っててIngress ControllerもGLBCを使ってなんか勝手にやってくれてるなみたいな感じで、 k8sを使う側そんなに気にしてなかったんですが、 EKSもくるということでAWSでやるにはどうすればいいだろうということを考え始めたというのが経緯です。

とりあえずIngressとは?

An Ingress is a collection of rules that allow inbound connections to reach the cluster services.

とある通り、外部からのリクエストを各サービスに振り分けるルールを書くことができます。 なので、外部のクラウドプロバイダ上で立てる場合、Ingressを使った方が無駄なLBをたてずにすむので色々節約になります。

    internet
        |
   [ Ingress ]
   --|-----|--
   [ Services ]

IngressにはIngress Controllerが必要です

Ingress ControllerはIngressというobjectが登録されたときに実際につながるようにする処理をしてくれるcontrollerです。 Kubernetesはこういうcontrollerがいっぱいいて、他のobjectも同じようにobject登録すると、controllerがeventをpollingして見張っていて変化があれば何かをするというアーキテクチャになっています。素晴らしいですね。早く人間を置き換えてくれ

f:id:masato47744:20180410222545p:plain

Ingress Controllerどれにする??

ということで本題ですが、kopsでKubernetesを構築したときにはまだIngress Controllerはいません。要はなんだっていいんですが、とはいえ有名どころを使いたいしということでちょっと悩んでいます。

まずAWSでIngress Controllerやるならたいていこの3つのどれかかなということころまではググってなんとなく掴みました。

AWS使ってる身としてはALBやACMなどAWSに統合されていてほしい

AWSにはいつかEKSもくるだろうしある程度統合されているような仕組みでIngressをやりたい。 さらにHTTPで振り分けルールといえば当然ALBが思い浮かぶわけです。

ということで、alb-ingress-controllerkube-ingress-aws-controllerというAWSのALBを使ったIngress Controllerで検討することにしました。

alb-ingress-controller

qiita.com

をとても参考にさせてもらいました。ありがとうございます、ありがとうございます。

作り方などはこちらの記事や、walkthroughも公式で用意されててドキュメントも親切で特にはまることなく使うことができました。

Ingressにannotationsを指定することで、ALBを起動するsubnetの指定や、ACMの指定、security groupの指定、ALBのlistener ruleを使った振り分けなどやりたいことはほとんどできて、これが顧客が求めていたものだとなったんですが、ちょっと要件を満たせないものが・・

IngressのHealth check pathがALBごとにしか指定できない

alb-ingress-controllerだとIngressがServiceのNodePortに対してHealth checkをするんですが、そのときのパスがALBごとにしか設定できないのです。 GKEのGLBCだとreadiness probeでできたのでそういうもんだと思ってました・・

Health checks

Currently, all service backends must satisfy either of the following requirements to pass the HTTP(S) health checks sent to it from the GCE loadbalancer:

  • Respond with a 200 on '/'. The content does not matter.
  • Expose an arbitrary URL as a readiness probe on the pods backing the Service.

PRも出てるけど霊圧が感じられない・・

こちらのPRでServiceにannotationを書くことでhealth check pathを指定できる提案がされてますが、ちょっと進捗が芳しくなさそう・・

github.com

OSSに参加しようという気持ちもあるので貢献していこうとも思いましたが、そもそもIngressのhealthcheckを個別に切り替えようという考えが邪悪なのかなという気にもなってきました。

/を全て何も処理せず200を返すようにアプリケーションを調整するのは難しそうなので、普通に各アプリケーション側に/healthzみたいなエンドポイントを作ってもらって200を返すようにしてもらうっていうのも解決策なんですが、インフラ構築側からするとアプリケーションを開発するエンジニアにそんなこと強要したくないなという思いがあります。

kube-ingress-aws-controller

ということでもう一つの候補ですが、kube-ingress-aws-controllerです。

qiita.com

これもこちらのサイトを参考にさせてもらいました、ありがとうございます、ありがとうございます。

kube-ingress-aws-controllerもACMやsubnet指定、security group指定などALBとしての機能は問題なさそうです。 当初kube-ingress-aws-controllerはALBのlistener ruleを使わずに、別途Ingress controllerがさらに必要ということを知り、やめようかと思ったんですが動的にcontrollerで解決するにはAWSにとらわれ過ぎてはいけないのかもしれないという気持ちになってきました。

さらにkopsのaddonとしても紹介されてるし、これが正攻法なのかという気にも・・

さらにさらに、別途必要なIngress ControllerであるSkipper自体も高機能でよさそうという印象です。

kube-ingress-aws-controller + Skipper の組み合わせであれば、alb-ingress-controllerで問題だったIngressからのhealth checkは単にskipperに対して行うだけでOKです。 あとは、Skipperが各Serviceに(NodePortじゃなくてClusterIPでOK)プロキシしてくれます。

まとめ

ここまで色々考えてきましたが、こういうIngress Controllerをどうするかっていうことを考えてくと、もしかして最近勉強会とかでよく連呼されているIstioとかLinkerdとかにいきつくのではないかという気になってきました。ただ、まだそれらがなんなのかちゃんと分かってないので、追いつくにはもう少し時間が必要です。