on-premise コンテナ基盤と hardware lb を使った "type loadbalancer"
TRANSCRIPT
On-premise コンテナ基盤と
Hardware LB を使った “type LoadBalancer”
@サイバーエージェントとさくらインターネットのインフラ談義
青山 真也 (Masaya Aoyama)
普段の主な仕事↓
世界で 138 番目
https://adtech.cyberagent.io/techblog/archives/3086
adtech studio のプライベートクラウド環境
・OpenStack をベースとしたプライベートクラウド環境
・Network のレイテンシが許容されないアドテクシステム
そんな弊社にも Production で利用可能な
GKE ライクなコンテナ基盤
AKE (Adtech Container Engine)
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&utm_medium=feed&utm_campaign=Feed:+ClPlBl+(Cloud+Platform+Blog)
みなさん Kubernetes って
どういう環境で利用されていますか?
素の Kubernetes を構築した場合
① Dynamic Persistent Volume Provisioning が使えない
○ PVC の要求に応じて PV を動的に払い出す機能
3 GB の Persistent Volume 頂戴!
5 GBの Persistent Volume あげる!
5GB
10 GB7 GB
事前に作成
事前に作成する手間、容量の無駄が発生しやすい
素の Kubernetes を構築した場合
① Dynamic Persistent Volume Provisioning が使えない
○ PVC の要求に応じて PV を動的に払い出す機能
3 GB の Persistent Volume 頂戴!
3 GBの Persistent Volume あげる!
3 GB
欲しいって言われたから作って渡そう
利用者の管理コストが低下
おいでおいで〜
…
素の Kubernetes を構築した場合
② type LoadBalancer Service が使えない
○ クラスタ外 LoadBalancer を作成する機能
おいでおいで〜
…
機能の実現と Cloud Provider① Dynamic Persistent Volume Provisioning
● Kubernetes の Cloud Provider 連携機能を利用
● Persistent Volume Plugin (ScaleIO, Flusterfs)
② type LoadBalancer
● Kubernetes の Cloud Provider 連携機能を利用○ 純粋なベアメタル /VM で Cloud Provider 連携してない場合は?
○ OpenStack で LBaaS 機能を利用していない場合は?
This is a slide title
今回は AKE の中でも、
LoadBalancer 周りの話をします。
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: v1kind: Servicemetadata: name: svc1spec: 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
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: v1kind: Servicemetadata: name: svc1spec: 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 ができない場合
VM αKubernets node
Internal
VM βKubernets node
52.0.0.1:80
LoadBalancer
External仮に Service が増えたことを考えると、こんな感じになります
52.0.0.1:80 > VM α:80 > VM β:8052.0.0.2:80 > VM α:80 > VM β:80
lo.0: 52.0.0.1:80lo.1: 52.0.0.2:80
lo.0: 52.0.0.1:80lo.1: 52.0.0.2:80
SNAT, NAPT ができない場合
VM αKubernets node
Internal
VM βKubernets node
52.0.0.1:80
LoadBalancer
External
52.0.0.1:80 > VM α:80 > VM β:8052.0.0.2:80 > VM α:80 > VM β:80
NodePort は Interface 全てでBind されてしまうため利用出来ない
例: *:80
apiVersion: v1kind: Servicemetadata: name: svc2spec: type: NodePort ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80
apiVersion: v1kind: Servicemetadata: name: svc1spec: type: NodePort ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80
lo.0: 52.0.0.1:80lo.1: 52.0.0.2:80
lo.0: 52.0.0.1:80lo.1: 52.0.0.2:80
SNAT, NAPT ができない場合
VM αKubernets node
Internal
VM βKubernets node
52.0.0.1:80
LoadBalancer
External
externalIPs 使えばいけないことも無いが …
利便性が著しく低い
…metadata: name: svc1spec: externalIPs: - 52.0.0.1 ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80
52.0.0.1:80 > VM α:80 > VM β:8052.0.0.2:80 > VM α:80 > VM β:80
…metadata: name: svc2spec: externalIPs: - 52.0.0.2 ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80
lo.0: 52.0.0.1:80lo.1: 52.0.0.2:80
lo.0: 52.0.0.1:80lo.1: 52.0.0.2:80
おいでおいで〜
…
This is a slide title① SNAT, NAPT が必須な構成
ボトルネック or リソースが必要
② 外部のコマンドでやってもらうの不便
やっぱりGKE がいいって言われる
VM αKubernets node
Internal
VM βKubernets node
52.0.0.1:80
LoadBalancer
External
52.0.0.1:80 > VM α:80 > VM β:8052.0.0.2:80 > VM α:80 > VM β:80
apiVersion: v1kind: Servicemetadata: name: svc2spec: type: ClusterIP ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80
apiVersion: v1kind: Servicemetadata: name: svc1spec: type: ClusterIP ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80
AKE 2.0 の構成 (ClusterIP + Metal LB)
VM αKubernets node
Internal
VM βKubernets node
52.0.0.1:80
LoadBalancer
External
52.0.0.1:80 > VM α:80 > VM β:8052.0.0.2:80 > VM α:80 > VM β:80
apiVersion: v1kind: Servicemetadata: name: svc2spec: type: ClusterIP ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80
apiVersion: v1kind: Servicemetadata: name: svc1spec: 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-* に転送
This is a slide title① SNAT, NAPT が必須な構成
ボトルネック or リソースが必要
② 外部のコマンドでやってもらうの不便
やっぱりGKE がいいって言われる
This is a slide titleやっぱ諦められない
type LoadBalancer
This is a slide title
① 外部 LoadBalancer の操作
② IP 払い出しの自動化
③ K8s Node の iptables 操作
type LoadBalancer のつくりかた
CloudProvider プラグインを自作しましょう。● LoadBalancer (今回はここの話 )● Routing● Host● Zone● BlockDevice
(参考)
インターフェースの一覧: pkg/cloudprovider/cloud.goOpenStack の場合、pkg/cloudprovider/providers/openstack/* 辺り
LoadBalancer 用の InterfaceGetLoadBalancer(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.Nameservice.Spec.LoadBalancerIPservice.Spec.Ports[].Portservice.Spec.Ports[].TargetPort
nodes.[].Name
This is a slide title
この 4 つの関数を作ると
VM αKubernets node
Internal
VM βKubernets node
52.0.0.1:80
LoadBalancer
External
52.0.0.1:80 > VM α:80 > VM β:8052.0.0.2:80 > VM α:80 > VM β:80
apiVersion: v1kind: Servicemetadata: name: svc2spec: type: LoadBalancer ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80
apiVersion: v1kind: Servicemetadata: name: svc1spec: type: LoadBalancer ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80
AKE 3.0 の構成 (LoadBalancer + Metal LB)
GKE などと全く同じ type LoadBalancer
今後オンプレにより求められるのは、パブリッククラウドとのシームレスな統合
コンテナ環境だとなおさら移行し易い
GKE > AKE & AKE > GKE
これでマルチクラウドでの展開も容易に
This is a slide title
ちょっとまった
Ingress ってのもいるよね?
おいでおいで〜
…
残すところ IngressHTTP LoadBalancer を提供する Ingress
● GKE 様だと L7 GCLB 様がいらっしゃられる
● それ以外は {nginx, nghttpx}-ingress-controller を使う○ ちょっと使い勝手が悪い、手間が多い、 GKE とは結構違う
現在 GKE Like に Ingress を使えるように controller を実装中。
● 12/1 の Kubernetes Advent Calender で公開予定