Slide 1

Slide 1 text

OpenStackとIngress Controllerで作る Container-nativeロードバランシング 牧垣 秀⼀朗 (Shuichiro MAKIGAKI) 株式会社サイバーエージェント 全社システム本部・adtech studio Cloud Native Days Tokyo 2019 / OpenStack Days Tokyo 2019

Slide 2

Slide 2 text

背景

Slide 3

Slide 3 text

株式会社サイバーエージェント • 株式会社サイバーエージェント(英称︓CyberAgent, Inc.)は、Ameba(アメーバブログ)関連事業とイン ターネット広告事業を主とする企業である。本社は東 京都渋⾕区に所在。⽇経平均株価の構成銘柄の⼀つ。 (Wikipedia: 2019-07-10)

Slide 4

Slide 4 text

adtech studio • 開発効率の向上、各サービスの技術⼒および精度強化 を⽬的に2013年10⽉1⽇に設⽴。サイバーエージェン トグループのアドテクノロジー分野におけるサービス 開発・提供を⾏う横断組織。 • 約200名のエンジニアと約100名のビジネスによって、 アドテクノロジー分野およびAI・ロボットサービス事 業におけるサービスを多数提供。 • エンジニア開発体制を強化するほか、エンジニアの技 術⼒向上をサポートする環境づくり、ビジネス側の知 識向上のサポートなど様々な制度の導⼊などを⾏って いる。

Slide 5

Slide 5 text

Infrastructure as a Service • IaaS︓2006~ (Wikipedia調べ)(浪⼈⽣→⼤学⽣くらいの時期……) • 流れの速い業界なので「早い・安い・旨い」IaaSが必要 Amazon Web Service, Google Compute Engine, On-premise Data Center, etc. 弊業界に限らないかもしれません • その時点で使えるもののうちで、最も適したもの選んで使う これができるのが弊社の強みです • On-premise環境にOpenStackでプライベートクラウド環境を構築

Slide 6

Slide 6 text

Adtech Container Engine • Kubernetes (k8s) on on-premise OpenStack • 通称「AKE」 • OpenStack Heat(CloudFormation相当)を使ってk8sク ラスタを1コマンドで構築 • 特徴 GKE 並に簡単なデプロイとスケーリング クラスタ外部から疎通できる VIP の払い出し Keystone 連携による Kubernetes Cluster への認証 Designate 連携による柔軟な FQDN によるアクセス 外部ボリュームの利⽤ (EBS 相当の Cinder 連携) NFSもサポート

Slide 7

Slide 7 text

本⽇話すこと オンプレのk8sで動いているコ ンテナに外部疎通性が欲しい •本質的には、やりたかったのはこれ だけ、なんですが…… •もちろんできなくはないんだけど、 ちょっと困る部分があって…… •それを何とかしたいのです •という発表です ところでKubernetesでそれをや るにはどうすればいいんでし たっけ︖

Slide 8

Slide 8 text

k8s Networkの復習 (1/3) • k8sクラスタは複数のノードから構成される • 今回の場合は、ノード==OpenStack Novaで 作ったVM LB VM Network Pod Network

Slide 9

Slide 9 text

k8s Networkの復習 (2/3) • VM NetworkとPod Networkが存在する • 実装は様々(VLAN, VXLAN, etc.) LB VM Network Pod Network

Slide 10

Slide 10 text

k8s Networkの復習 (3/3) • Pod Networkはクラスタ外からの疎通 性はない LB VM Network Pod Network VM

Slide 11

Slide 11 text

余談 • k8sの原型は「Borg」というGoogleの社内システム Verma, A., Pedrosa, L., Korupolu, M., Oppenheimer, D., Tune, E., & Wilkes, J. (2015, April). Large-scale cluster management at Google with Borg. In Proceedings of the Tenth European Conference on Computer Systems (p. 18). ACM. • ⾃分「いや、疎通できないの困らないの︖」 • 紙⽈く、In Borg, all tasks on a machine use the single IP address of their host, and thus share the host’s port space. … Kubernetes can take a more user-friendly approach that eliminates these complications: every pod and service gets its own IP address, allowing developers to choose ports… 超約︓ホストのIPを共有、ポートをやりくりする • つまりKubernetesは(他のやり⽅もあるので)Borgよりマシ(↑紙⽈く) 論⽂から察するにBorgの⽬的は「巨⼤な計算資源を効率よく使うこと」であって、コンテナとそのオーケ ストレーションは⼿段に過ぎなかった(と思われる) でもそれをインフラ抽象化としてOSSで売りに出したのはGoogleの巧みな術

Slide 12

Slide 12 text

問題

Slide 13

Slide 13 text

課題解決における3本の⽮(︖) コンテナ に外部疎 通性が欲 しい いろいろな⽅法 がある やってみると ちょっと問題が あった

Slide 14

Slide 14 text

`type: LoadBalancer` page 014

Slide 15

Slide 15 text

Balancing(kube-proxyのproxy-mode) • userspace Userspace上のkube-proxyがバランシング • iptables iptablesがバランシング kube-proxyはiptablesのエントリを管理 • ipvs ipvsがバランシング kube-proxyはipvsのエントリを管理 • 2段階ロードバランシング

Slide 16

Slide 16 text

となると、困ること(1) SRC IPがわからない •NATされてるから •通信制御・アクセス統計や解析など、送信元IPが必要となるケースは多い 弊社の外部LBはL4専⾨(BIG-IP) •重いのでL7は処理しない •よって、それ以外のどこかでX-Forwarded-Forを付与してほしい

Slide 17

Slide 17 text

そこでIngress • クラスタ内のServiceに対して、外部疎通性を与えるAPIオブジェクト https://kubernetes.io/docs/concepts/services-networking/ingress/ プロトコルはHTTPとHTTPSに対応 ロードバランシング、SSL終端、名前ベースのVirtual Hostの機能も提供する • 実体はNginxだったりnghttpxだったりする • このIngressをControlするのがIngress Controller 実体とControllerが同じPodだったりする(話がややこしい)

Slide 18

Slide 18 text

⾃作 Ingress Controller v1 • 2017-12~ • Ingress=L7ロードバランサーを作る • いい感じにリソースを操作することで、GKE-likeなIngressを実現 • Controller によりオペレーションを⾃動化 1. Ingressリソースのingress-classを変更 2. Nginx-IngressのDeploymentを作成(上記のingress-classを指定) 3. Serviceを作成

Slide 19

Slide 19 text

となると、困ること(2) L4 LB VM Network Pod Network 必要なリソース • Deployment (Nginx Ingress) • Service(type: LoadBalancer) L7を処理するPodを作成してオフロード

Slide 20

Slide 20 text

困ること(まとめ) 結局、SRC IPはわからない • NATされてるから • 通信制御・アクセス統計や解析など、送信元IPが必要となるケースは多い 弊社の外部LBはL4専⾨(BIG-IP) • 処理が重すぎるのでL7は処理しない • それ以外のどこかでX-Forwarded-Forを付与してほしい DeploymentやService などをいちいち作る必要がある ingress-classを利⽤しないとリソースごとに分離できない

Slide 21

Slide 21 text

なんかもうL4LB配下にIngressぶら下げて、 そこでX-FF付けちゃって、 そこからコンテナに直接パケット通して︕ → Container-native load balancing+Ingress 駄々をこねる⼈のイラスト(男の⼦)

Slide 22

Slide 22 text

⾃作 Ingress Controller

Slide 23

Slide 23 text

Container-native LB L4 LB VM Network Pod Network VM . VM . L7 LBを外側に構築 L4 LB v1 L4 LB VM . v2

Slide 24

Slide 24 text

Container-native LB L4 LB VM Network Pod Network VM . VM . Calico により VM から Pod への 疎通性確保

Slide 25

Slide 25 text

Calico? • 読み︓キャリコ Scalable, distributed control plane Policy-driven network security No overlay required Pluggable Data Plane Integrated with all major cloud platforms Widely deployed, and proven at scale • TL;DR: BGPでコンテナへの経路を得る Pod IPへの経路を広報して、ホストのIPに吸い込む つまりBIRDのControllerとも⾔える それをやっちゃえば、それはできそう(⽇本語)

Slide 26

Slide 26 text

Calico⼤変そう︖ • VM に対して伝搬しているだけ • Nginx IngressからPodへの疎通性を確保 L4 LB VM Network Pod Network VM .

Slide 27

Slide 27 text

Calico⼤変そう︖ • 既存のNginx Ingressを利⽤することで⼤幅な実装コストダウンできそう Nginx Ingressの各エントリは、もともとPodのIPアドレス 構築・運⽤の範囲をController化するだけでよさそう VM . VM Network Pod Network L4 LB L4 LB VM .

Slide 28

Slide 28 text

⾃作V2 (Container-native) に向けて • Controller が⻩⾊い部分を作成 • 先ほどの Deployment の代わり にVM Cluster を構築する • OpenStack Heatを使⽤ OpenStack Heat ≒ CloudFormation L4 LB VM Network Pod Network VM . VM .

Slide 29

Slide 29 text

余談 • そこまでしてやる意味あるの︖無理してない︖ Q︓外部LBみたいな転職できない技術使わないで、オープン・スタンダードなk8sの世界にすべて ⼊れれば理想なのでは︖Googleが作ってるんだし。 A︓No 既存のリソースを活⽤できるのが、Kubernetesのいいところ • コンピュータエンジニアの所作︓あるなら使う、ダメなら直す、無いなら作る それが価値の創造 • ※個⼈の感想です • ※諸説あります

Slide 30

Slide 30 text

作る

Slide 31

Slide 31 text

開発のPhase分け Phase 1: Ingress ControllerだけでMonolithicに動かす • レプリカ数など管理するものが多い、コントロール対象(関⼼事)は狭めたい Phase 2: HeatStack Controllerを分離 • Heatのスタック状態を⾒る部分を別のControllerとして分離 • 状態管理ループの中で⼤きな「待ち」を⼊れるのは、得策ではない • さっきの紙︓”Borgmaster was originally designed as a monolithic system, but over time, … , we split off the scheduler and the primary UI (Sigma) into separate processes, and added services for admission control, vertical and horizontal auto-scaling, re- packing tasks, periodic job submission (cron), workflow management, and archiving system actions for off-line querying.” • 超約︓Monolithicはやっぱりスケールしないわ • Heatの待ちが移動しただけだが、ロック粒度は⼩さくなった

Slide 32

Slide 32 text

Controller超約 • あるべきリソースを定義して、保管して おく よって、保管されている定義が常に「真」 「真」が間違っているのは、オペミス扱い • 常に現在のリソース状態を監視し、ある べき状態との差分が出ると、収束させよう とする 取得 • APIサーバーへ 問い合わせる 照合 • あるべき姿と現 状を照合する 実⾏ • 差分があれば埋 めて収束させる

Slide 33

Slide 33 text

⾃作Ingress Controller • kubeconfigの構築とHeatへの引き渡し Ingressが動く実VMはk8sの「外」にあるので、 kubeconfigを渡さないとクラスタの状態を知るこ とができない これ実装が意外とめんどくさいんですよ(70⾏くらい) • Heat Stackの作成 +Annotation経由で来るパラメータのValidation 正確にはHeatStackカスタムリソースの登録 実際にHeatを叩くのはHeatStack Controller apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-sample annotations: ake.adtech.cyberagent.io/ingress-controller-flavor ake.adtech.cyberagent.io/ingress-controller-replicas ake.adtech.cyberagent.io/fluentd-s3-bucket # etc. spec: rules: - http: paths: - path: /a backend: serviceName: np-a servicePort: 80

Slide 34

Slide 34 text

⾃作HeatStack Controller • HeatStack CRD (Custom Resource Definition) カスタムしたリソースの定義(そのまま) つまりHeatのStackをk8sのリソースとして管理 の対象にさせる Spec (あるべき状態): TemplateURL, Timeout, Params, Tags Status (実際の状態): StackStatus, LastOutputs, LastParams HeatのOutputと同期 • VMとLBの状態管理に集中 取得 • APIサーバーへ 問い合わせる 照合 • あるべき姿と現 状を照合する 実⾏ • 差分があれば埋 めて収束させる

Slide 35

Slide 35 text

Heatをカスタム • LB (BIG-IP) を操作できるHeatのカスタム リソースを⾃作 プール、メンバー、Virtual ServerをHeatのリ ソースとして指定可能 1. BIGIPPoolとBIGIPVSを準備 2. Nova::ServerでVMを作って 3. BIGIPPoolMemberとする • こういうのが既存なので楽です resource_group_anlb: type: OS::Heat::ResourceGroup resource_def: instances_anlb: type: OS::Nova::Server bigip_poolmember_anlb: type: ADTECH::AXC::BIGIPPoolMember bigip_pool_anlb: type: ADTECH::AXC::BIGIPPool bigip_vs_anlb_v2: type: ADTECH::AXC::BIGIPVS

Slide 36

Slide 36 text

Heatでやること • インスタンスの中でやること → あと全部cloud_initでやる cloud_init_anlb: type: "OS::Heat::MultipartMime" properties: parts: - config: {get_resource: cloud_init_anlb_11_set_sysctl} - config: {get_resource: cloud_init_anlb_12_set_kubeconfig_calico} - config: {get_resource: cloud_init_anlb_13_set_kubeconfig_ingress} - config: {get_resource: cloud_init_anlb_14_set_interface} - config: {get_resource: cloud_init_anlb_15_set_bgppeer_yaml} - config: {get_resource: cloud_init_anlb_16_set_bird_config} - config: {get_resource: cloud_init_anlb_17_set_dd_config} - config: {get_resource: cloud_init_anlb_18_set_fluentd_config} - config: {get_resource: cloud_init_anlb_19_set_run_script} - config: {get_resource: cloud_init_anlb_20_set_logrotate} - config: {get_resource: cloud_init_anlb_99_wc_notify}

Slide 37

Slide 37 text

Validating Webhook • レプリカ以外が書き換えられると困る すべての VM を再構築してしまう可能性あり (Heat の仕様)(マジかよ) • そこでValidating Webhookも作成 しないで欲しいParamsの変更はRejectされる kind: HeatStack metadata: name: sample-stack spec: templateURL: http://.../cls.yaml params: replicas: "3" flavor: ar1-standard-4 ingress_name: sample-ingress kubeconfig: ... status: lastOutput: bigip_vsip: x.x.x.x stackStatus: CREATE_COMPLETE

Slide 38

Slide 38 text

実装 • Gophercloud: SDK for OpenStack ちょいちょいバグっぽい愛嬌のある⼦です • Kubebuilder: SDK for building Kubernetes APIs using CRDs https://github.com/kubernetes-sigs/kubebuilder LoopはSDK任せで、イベント発⽣時のロジックを書いていくイメージ こういうのがちゃんと提供されているのがとても良い ちゃんと動いちゃって愛嬌がない • Editor(Go⾔語) Atom / VS Code / Vim / Goland (←⾃分) / Emacs (←⾃分) • Workflow → Pull Requestする → ReviewしてMergeする → 動かしてみるが、問題がみつかる → 直す → 最初に戻る

Slide 39

Slide 39 text

うん、で、実際は︖ • Commit数で⾒ると超絶優秀な⼯数 • ⽴ちふさがる困難で⾒ると 書くには余⽩がたりない

Slide 40

Slide 40 text

まとめ

Slide 41

Slide 41 text

まとめ(教科書的) CalicoによるContainer-native load balancingと、Ingress Controllerの独⾃実装 • 以下の問題を解決できた • SRC IPがわからない・外部LBはL4専⾨・単純なIngressだとDeploymentなどを作る必要がある 賢いSDKと少⼈数チームで、短期間で実装 • たいへんよくできました 使ってみたの︖ • ちょうど社内Wikiのインフラ刷新案件があったので、さっそく適⽤ • 動いてくれています(感動) 性能(RPS) • 1台: 1734~3529 → 2台: 3874~5520 → 3台: 5735~8446 • もうひとこえ︖まだまだ仕事があってうれしいなぁ(遠い⽬)

Slide 42

Slide 42 text

まとめ(本質) •オンプレ資産の活⽤法が増えた • オンプレは価格的に競争⼒が⾼い • そこでGKEみたいな機能が(全部じゃないけど)最低限使える • AWSやGCP以外にもう⼀つのクラウドの選択肢が維持できる •アプリケーション抽象化により、インフラ屋さんサイ ドは楽になった •プライベートクラウドの成⻑と、その機能が増えてい くことを⽰せた • そうやってLBとコンテナって連携すればいいのか、というのを⽰せた • これをインフラチームから⾔える、のは強み この仕事の価値 とは︖