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

Kubernetes をいじって Hardware LoadBalancer で "type LoadBalancer" を実現してみた @Kubernetes meetup #7

Kubernetes をいじって Hardware LoadBalancer で "type LoadBalancer" を実現してみた @Kubernetes meetup #7

CyberAgent adtech studio ではプライベートクラウド環境があり、その中で GKE 互換の AKE 環境を動作させています。
AKE 環境ではHardware LoadBalancer との連携が必要となっており、type LoadBalancer を利用するために Cloud Provider を独自実装した話となります。
本スライドは Kubernetes Meetup #7 で発表した内容となります。

発表内容
https://youtu.be/kjK-LpvfZFU?t=6834

De266761b955b2636e454a1bc7a99ed4?s=128

Masaya Aoyama (@amsy810)

October 13, 2017
Tweet

Transcript

  1. Hardware LoadBalancer で “type LoadBalancer”を 使ってみた

  2. 青山 真也 (Masaya Aoyama) 普段の主な仕事↓ ← 結果待ち

  3. adtech studio のプライベートクラウド環境 ・OpenStack をベースとしたプライベートクラウド環境 ・Network のレイテンシが許容されないアドテクシステム そんな弊社にも GKE ライクなコンテナ基盤がございます。

    Adtech Container Engine
  4. This is a slide title AKE の中でも、 LoadBalancer 周りの話をします。

  5. 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
  6. 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
  7. 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
  8. 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
  9. 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
  10. おいでおいで〜 …

  11. This is a slide title ① SNAT, NAPT が必須な構成 ボトルネック

    or リソースが必要 ② 外部のコマンドでやってもらうの不便 やっぱりGKE がいいって言われる
  12. 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)
  13. 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-* に転送
  14. This is a slide title ① SNAT, NAPT が必須な構成 ボトルネック

    or リソースが必要 ② 外部のコマンドでやってもらうの不便 やっぱりGKE がいいって言われる
  15. This is a slide title ① 外部 LoadBalancer の操作 ②

    IP 払い出しの自動化 ③ K8s Node の iptables 操作
  16. This is a slide title やっぱ諦められないよ type LoadBalancer

  17. type LoadBalancer のつくりかた CloudProvider を自作しましょう。 • LoadBalancer (今回はここの話) • Routing

    • Host • Zone • BlockDevice (参考) インターフェースの一覧: pkg/cloudprovider/cloud.go OpenStack の場合、pkg/cloudprovider/providers/openstack/* 辺り
  18. 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
  19. This is a slide title この 4 つの関数を作ると

  20. 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
  21. 今後オンプレにより求められるのは、 パブリッククラウドとのシームレスな統合 コンテナ環境だとなおさら移行し易い GKE > AKE & AKE > GKE これでマルチクラウドでの展開も容易に