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

CyberAgent: How We Deployed Production Kubernet...

CyberAgent: How We Deployed Production Kubernetes Clusters on OpenStack without L3 Network / OpenStack seminar without L3 k8s LB

CyberAgent: How We Deployed Production Kubernetes Clusters on OpenStack without L3 Network

@OpenStack最新情報セミナー 2017/11
CFPに落ちたが現地で話したかった俺の話

Masaya Aoyama (@amsy810)

November 15, 2017
Tweet

More Decks by Masaya Aoyama (@amsy810)

Other Decks in Technology

Transcript

  1. CyberAgent: How We Deployed Production Kubernetes Clusters on OpenStack without

    L3 Network @OpenStack最新情報セミナー 2017/11 CFPに落ちたが現地で話したかった俺の話
  2. GKE が Google Kubernetes Engine に GKE = Google Container

    Engine AKE = Adtech Container Engine 参考: https://cloudplatform.googleblog.com/2017/11/introducing-Certified-Kubernetes-and-Google-Kubernetes-Engine.html?utm_source=feedburner&ut m_medium=feed&utm_campaign=Feed:+ClPlBl+(Cloud+Platform+Blog)
  3. Heat の Custom Resource Plugins を自作 LoadBalancer を操作して VIP の払い出し

    (自動割当て機構を含む) 参考: https://adtech.cyberagent.io/techblog/archives/2594
  4. 素の Kubernetes を構築した場合 ① Dynamic Persistent Volume Provisioning が使えない ◦

    PVC の要求に応じて PV を動的に払い出す機能 3 GB の Persistent Volume 頂戴! 5 GBの Persistent Volume あげる! 5GB 10 GB 7 GB 事前に作成 事前に作成する手間、容量の無駄が発生しやすい
  5. 素の Kubernetes を構築した場合 ① Dynamic Persistent Volume Provisioning が使えない ◦

    PVC の要求に応じて PV を動的に払い出す機能 3 GB の Persistent Volume 頂戴! 3 GBの Persistent Volume あげる! 3 GB 欲しいって言われたから 作って渡そう 利用者の管理コストが低下
  6. 別の手段: type NodePort の話 eth0: 10.0.0.1:34567 VM α Kubernets node

    Internal VM β Kubernets node apiVersion: v1 kind: Service metadata: name: svc1 spec: type: NodePort ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 eth0: 10.0.0.2:34567
  7. AKE 1.0 の構成 (NodePort + Metal LB) eth0: 10.0.0.1:34567 VM

    α Kubernets node Internal VM β Kubernets node 52.0.0.1:80 LoadBalancer External apiVersion: v1 kind: Service metadata: name: svc1 spec: type: NodePort ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 52.0.0.1:80 > 10.0.0.1:34567 > 10.0.0.2:34567 (別途登録が必要) eth0: 10.0.0.2:34567 SNAT + NAPT
  8. AKE 1.0 の構成 (NodePort + Metal LB + (HAProxy)) VM

    α Kubernets node Internal VM β Kubernets node 52.0.0.1:80 LoadBalancer (+ HAProxy) External 52.0.0.1:80 > 10.0.0.1:34567 > 10.0.0.2:34567 (別途登録が必要) apiVersion: v1 kind: Service metadata: name: svc1 spec: type: NodePort ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 eth0: 10.0.0.1:34567 eth0: 10.0.0.2:34567 SNAT + NAPT
  9. This is a slide title ① SNAT, NAPT が必須な構成 ボトルネック

    or リソースが必要 ② 外部のコマンドでやってもらうの不便 自動 IP 払い出しとかも無い上、二度手間
  10. 機能の実現と Cloud Provider ① Dynamic Persistent Volume Provisioning • Kubernetes

    の Cloud Provider 連携機能を利用 • Persistent Volume Plugin (ScaleIO, Flusterfs) ② type LoadBalancer • Kubernetes の Cloud Provider 連携機能を利用 ◦ 純粋なベアメタル/VM で Cloud Provider 連携してない場合は? ◦ OpenStack で LBaaS 機能を利用していない場合は? ▪ Neutron L3 Agent、Octavia は未使用
  11. Kubernetes の CoudProvider プラグイン CloudProvider プラグインには主に下記のようなものがあります • Routing • Host

    • Zone • BlockDevice • LoadBalancer (今回はここの話) (参考) インターフェースの一覧: pkg/cloudprovider/cloud.go OpenStack の場合、pkg/cloudprovider/providers/openstack/* 辺り
  12. Kubernetes の CloudProvider 連携機能(LBaaS) ① CloudProvider 連携で Neutron に LB

    の作成依頼 ② Octavia で LB を作成(LBaaS v1 は 1.8.0 で打ち切り)
  13. This is a slide title Kubernetes の CloudProvider 連携機能(LBaaS) ①

    CloudProvider 連携で Neutron に LB の作成依頼 ② BIG-IP で LB を作成(多分プラグイン書けばいけるのかな…)
  14. This is a slide title Kubernetes の CloudProvider 連携機能(LBaaS) ①

    Kubernetes の CloudProvider 連携のコードを変更して、   直接 BIG-IP を操作
  15. LoadBalancer 用の Interface GetLoadBalancer(clusterName string, service *v1.Service)  ・あまり変える部分はない EnsureLoadBalancer(clusterName string,

    service *v1.Service, nodes []*v1.Node)  ・LoadBalancer を作成する、IP の指定がない場合は自動アサイン UpdateLoadBalancer(clusterName string, service *v1.Service, nodes []*v1.Node)  ・LoadBalancer を更新する EnsureLoadBalancerDeleted(clusterName string, service *v1.Service)  ・LoadBalancer を削除する 大まかには上記 3 種類の Interface を実装してあげる形 渡ってくる構造体に必要な情報は大体揃っている service.Name service.Spec.LoadBalancerIP service.Spec.Ports[].Port service.Spec.Ports[].TargetPort nodes.[].Name
  16. 残すところ Ingress HTTP LoadBalancer を提供する Ingress • GKE 様だと L7

    GCLB 様がいらっしゃられる • それ以外は {nginx, nghttpx}-ingress-controller を使う ◦ ちょっと使い勝手が悪い、手間が多い、 GKE とは結構違う 現在 GKE Like に Ingress を使えるように controller を実装中。 • 12/1 の Kubernetes Advent Calender で公開予定
  17. AKE 1.0 の構成 (NodePort + Metal LB) eth0: 10.0.0.1:34567 VM

    α Kubernets node Internal VM β Kubernets node 52.0.0.1:80 LoadBalancer External apiVersion: v1 kind: Service metadata: name: svc1 spec: type: NodePort ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 52.0.0.1:80 > 10.0.0.1:34567 > 10.0.0.2:34567 (cli で登録が必要) eth0: 10.0.0.2:34567
  18. AKE 1.0 の構成 (NodePort + Metal LB + (HAProxy)) VM

    α Kubernets node Internal VM β Kubernets node 52.0.0.1:80 LoadBalancer (+ HAProxy) External 52.0.0.1:80 > 10.0.0.1:34567 > 10.0.0.2:34567 (cli で登録が必要) apiVersion: v1 kind: Service metadata: name: svc1 spec: type: NodePort ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 eth0: 10.0.0.1:34567 eth0: 10.0.0.2:34567
  19. SNAT, NAPT ができない場合 VM α Kubernets node Internal VM β

    Kubernets node 52.0.0.1:80 LoadBalancer External 仮に Service が増えたことを考えると、 こんな感じになります 52.0.0.1:80 > VM α:80 > VM β:80 52.0.0.2:80 > VM α:80 > VM β:80 lo.0: 52.0.0.1:80 lo.1: 52.0.0.2:80 lo.0: 52.0.0.1:80 lo.1: 52.0.0.2:80
  20. SNAT, NAPT ができない場合 VM α Kubernets node Internal VM β

    Kubernets node 52.0.0.1:80 LoadBalancer External 52.0.0.1:80 > VM α:80 > VM β:80 52.0.0.2:80 > VM α:80 > VM β:80 NodePort は Interface 全てで Bind されてしまうため利用出来ない 例: *:80 apiVersion: v1 kind: Service metadata: name: svc2 spec: type: NodePort ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 apiVersion: v1 kind: Service metadata: name: svc1 spec: type: NodePort ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 lo.0: 52.0.0.1:80 lo.1: 52.0.0.2:80 lo.0: 52.0.0.1:80 lo.1: 52.0.0.2:80
  21. SNAT, NAPT ができない場合 VM α Kubernets node Internal VM β

    Kubernets node 52.0.0.1:80 LoadBalancer External externalIPs 使えば いけないことも無いが … 利便性が著しく低い … metadata: name: svc1 spec: externalIPs: - 52.0.0.1 ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 52.0.0.1:80 > VM α:80 > VM β:80 52.0.0.2:80 > VM α:80 > VM β:80 … metadata: name: svc2 spec: externalIPs: - 52.0.0.2 ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 lo.0: 52.0.0.1:80 lo.1: 52.0.0.2:80 lo.0: 52.0.0.1:80 lo.1: 52.0.0.2:80
  22. This is a slide title ① SNAT, NAPT が必須な構成 ボトルネック

    or リソースが必要 ② 外部のコマンドでやってもらうの不便 やっぱりGKE がいいって言われる
  23. VM α Kubernets node Internal VM β Kubernets node 52.0.0.1:80

    LoadBalancer External 52.0.0.1:80 > VM α:80 > VM β:80 52.0.0.2:80 > VM α:80 > VM β:80 apiVersion: v1 kind: Service metadata: name: svc2 spec: type: ClusterIP ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 apiVersion: v1 kind: Service metadata: name: svc1 spec: type: ClusterIP ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 AKE 2.0 の構成 (ClusterIP + Metal LB)
  24. VM α Kubernets node Internal VM β Kubernets node 52.0.0.1:80

    LoadBalancer External 52.0.0.1:80 > VM α:80 > VM β:80 52.0.0.2:80 > VM α:80 > VM β:80 apiVersion: v1 kind: Service metadata: name: svc2 spec: type: ClusterIP ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 apiVersion: v1 kind: Service metadata: name: svc1 spec: type: ClusterIP ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 AKE 2.0 の構成 (ClusterIP + Metal LB) 自前で動的に iptables を書き換えて頑張る (listen しない、ClusterIP を利用) 52.0.0.1:80 宛にきたパケットを 該当 Service の KUBE-SVC-* に転送
  25. This is a slide title ① SNAT, NAPT が必須な構成 ボトルネック

    or リソースが必要 ② 外部のコマンドでやってもらうの不便 やっぱりGKE がいいって言われる
  26. VM α Kubernets node Internal VM β Kubernets node 52.0.0.1:80

    LoadBalancer External 52.0.0.1:80 > VM α:80 > VM β:80 52.0.0.2:80 > VM α:80 > VM β:80 apiVersion: v1 kind: Service metadata: name: svc2 spec: type: LoadBalancer ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 apiVersion: v1 kind: Service metadata: name: svc1 spec: type: LoadBalancer ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 AKE 3.0 の構成 (LoadBalancer + Metal LB) GKE などと全く同じ type LoadBalancer