cyberagent: how we deployed production kubernetes clusters on openstack without l3 network -...

Post on 21-Jan-2018

666 Views

Category:

Technology

4 Downloads

Preview:

Click to see full reader

TRANSCRIPT

CyberAgent: How We Deployed Production Kubernetes Clusters

on OpenStack without L3 Network

青山 真也 (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 って

どういう環境で利用されていますか?

L3 Network の機能が必要

LoadBalancer as a Service が必要

細かい設定が困難

成熟度が高くはない

OpenStack 界隈の方々だと…

AKE の場合

Resource Group として作成し、スケーリング可能に Interface は別の Resource Group として作成し、 Master 構築時に全 IP Address を利用(etcd など)

Heat の Custom Resource Plugins を自作

LoadBalancer を操作して VIP の払い出し

(自動割当て機構を含む)

参考: https://adtech.cyberagent.io/techblog/archives/2594

Designate を使った簡易 DNS Round Robinクライアントからはクラスタ名だけで疎通可能になる VIPが

必要な場合、CLI からopenstack stack show して

 取得する必要があるが、結構レスポンスが悪いので …

Kubernetes の OpenStack Integration 機能(後述)を

有効化する設定をした 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 を作成する機能

別の手段: type NodePort の話

eth0: 10.0.0.1:34567

VM αKubernets node

Internal

VM βKubernets node

apiVersion: v1kind: Servicemetadata: name: svc1spec: type: NodePort ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80

eth0: 10.0.0.2:34567

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(別途登録が必要)

eth0: 10.0.0.2:34567

SNAT + NAPT

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: 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

This is a slide title① SNAT, NAPT が必須な構成

ボトルネック or リソースが必要

② 外部のコマンドでやってもらうの不便

自動 IP 払い出しとかも無い上、二度手間

おいでおいで〜

機能の実現と 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 は未使用

Kubernetes の CoudProvider プラグイン

CloudProvider プラグインには主に下記のようなものがあります● Routing● Host● Zone● BlockDevice● LoadBalancer (今回はここの話 )

(参考)

インターフェースの一覧: pkg/cloudprovider/cloud.goOpenStack の場合、pkg/cloudprovider/providers/openstack/* 辺り

This is a slide title

今回は AKE の中でも、

LoadBalancer 周りの話をします。

Kubernetes の CloudProvider 連携機能(LBaaS)

① CloudProvider 連携で Neutron に LB の作成依頼

② Octavia で LB を作成(LBaaS v1 は 1.8.0 で打ち切り)

This is a slide titleKubernetes の CloudProvider 連携機能(LBaaS)

① CloudProvider 連携で Neutron に LB の作成依頼

② BIG-IP で LB を作成(多分プラグイン書けばいけるのかな…)

This is a slide titleKubernetes の CloudProvider 連携機能(LBaaS)

① Kubernetes の CloudProvider 連携のコードを変更して、

  直接 BIG-IP を操作

This is a slide title

① 外部 LoadBalancer の操作

② IP 払い出しの自動化

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

今後オンプレにより求められるのは、パブリッククラウドとのシームレスな統合

コンテナ環境だとなおさら移行し易い

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 で公開予定

This is a slide title

付録

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 がいいって言われる

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

top related