Upgrade to Pro — share decks privately, control downloads, hide ads and more …

OpenStackとIngress Controllerで作るContainer-nativeロードバランシング

OpenStackとIngress Controllerで作るContainer-nativeロードバランシング

Shuichiro MAKIGAKI

July 23, 2019
Tweet

More Decks by Shuichiro MAKIGAKI

Other Decks in Technology

Transcript

  1. adtech studio • 開発効率の向上、各サービスの技術⼒および精度強化 を⽬的に2013年10⽉1⽇に設⽴。サイバーエージェン トグループのアドテクノロジー分野におけるサービス 開発・提供を⾏う横断組織。 • 約200名のエンジニアと約100名のビジネスによって、 アドテクノロジー分野およびAI・ロボットサービス事

    業におけるサービスを多数提供。 • エンジニア開発体制を強化するほか、エンジニアの技 術⼒向上をサポートする環境づくり、ビジネス側の知 識向上のサポートなど様々な制度の導⼊などを⾏って いる。
  2. Infrastructure as a Service • IaaS︓2006~ (Wikipedia調べ)(浪⼈⽣→⼤学⽣くらいの時期……) • 流れの速い業界なので「早い・安い・旨い」IaaSが必要 Amazon

    Web Service, Google Compute Engine, On-premise Data Center, etc. 弊業界に限らないかもしれません • その時点で使えるもののうちで、最も適したもの選んで使う これができるのが弊社の強みです • On-premise環境にOpenStackでプライベートクラウド環境を構築
  3. 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もサポート
  4. 余談 • 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の巧みな術
  5. ⾃作 Ingress Controller v1 • 2017-12~ • Ingress=L7ロードバランサーを作る • いい感じにリソースを操作することで、GKE-likeなIngressを実現

    • Controller によりオペレーションを⾃動化 1. Ingressリソースのingress-classを変更 2. Nginx-IngressのDeploymentを作成(上記のingress-classを指定) 3. Serviceを作成
  6. となると、困ること(2) L4 LB VM Network Pod Network 必要なリソース • Deployment

    (Nginx Ingress) • Service(type: LoadBalancer) L7を処理するPodを作成してオフロード
  7. 困ること(まとめ) 結局、SRC IPはわからない • NATされてるから • 通信制御・アクセス統計や解析など、送信元IPが必要となるケースは多い 弊社の外部LBはL4専⾨(BIG-IP) • 処理が重すぎるのでL7は処理しない

    • それ以外のどこかでX-Forwarded-Forを付与してほしい DeploymentやService などをいちいち作る必要がある ingress-classを利⽤しないとリソースごとに分離できない
  8. Container-native LB L4 LB VM Network Pod Network VM .

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

    VM . Calico により VM から Pod への 疎通性確保
  10. 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とも⾔える それをやっちゃえば、それはできそう(⽇本語)
  11. ⾃作V2 (Container-native) に向けて • Controller が⻩⾊い部分を作成 • 先ほどの Deployment の代わり

    にVM Cluster を構築する • OpenStack Heatを使⽤ OpenStack Heat ≒ CloudFormation L4 LB VM Network Pod Network VM . VM .
  12. 開発の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の待ちが移動しただけだが、ロック粒度は⼩さくなった
  13. ⾃作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
  14. ⾃作HeatStack Controller • HeatStack CRD (Custom Resource Definition) カスタムしたリソースの定義(そのまま) つまりHeatのStackをk8sのリソースとして管理

    の対象にさせる Spec (あるべき状態): TemplateURL, Timeout, Params, Tags Status (実際の状態): StackStatus, LastOutputs, LastParams HeatのOutputと同期 • VMとLBの状態管理に集中 取得 • APIサーバーへ 問い合わせる 照合 • あるべき姿と現 状を照合する 実⾏ • 差分があれば埋 めて収束させる
  15. 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
  16. 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}
  17. 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
  18. 実装 • 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する → 動かしてみるが、問題がみつかる → 直す → 最初に戻る
  19. まとめ(教科書的) 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 • もうひとこえ︖まだまだ仕事があってうれしいなぁ(遠い⽬)
  20. まとめ(本質) •オンプレ資産の活⽤法が増えた • オンプレは価格的に競争⼒が⾼い • そこでGKEみたいな機能が(全部じゃないけど)最低限使える • AWSやGCP以外にもう⼀つのクラウドの選択肢が維持できる •アプリケーション抽象化により、インフラ屋さんサイ ドは楽になった

    •プライベートクラウドの成⻑と、その機能が増えてい くことを⽰せた • そうやってLBとコンテナって連携すればいいのか、というのを⽰せた • これをインフラチームから⾔える、のは強み この仕事の価値 とは︖