repl.info

Kubernetes on OpenStack with Octaviaでスケーラブルなロードバランサーを実現する

KubernetesのCloud-ProviderはOpenStackのLoadBalancerをサポートしている。v1.9からOctaviaがサポートされたので、kubesprayで構築して試した。OctaviaについてはOpenStack Octaviaの概要を参照していただきたい。

構築自体はkubesprayのmasterなどv1.9以降が使えるもので設定して、かつcloud-configファイルのLoadBalancerセクションでuse-octavia=trueとなるようにテンプレートを修正する。その後ansibleを適用したらよいのだけど、kubernetes v1.9.1だと動かない。というのも、バグでLoadBalancer作成中に叩くAPIエンドポイントが間違っていた。

すでに修正済みかつv1.9.3に修正が含まれると思われるが、今すぐためしたかったのでv1.9.1のタグからブランチを切り、修正PRをcherry-pickし、イメージをビルドして検証を継続した。gophercloudを使ってOpenStackのAPIを叩いていれば読みやすいので助かる。hyperkubeをビルドする時、デフォルトだと全OSかつ全アーキテクチャ向けにビルドするようで滅茶苦茶時間がかかるので、Kubernetes: Build Your Custom Kubelet Imageのように環境変数で指定してあげるのがよいです。それでもイメージを作るのに15分くらいはかかる(体感)ので、なんかいい方法ないものか。

検証用には microservices-demoを使っていて、front-end ServiceのtypeをLoadBalancerに変更すればよい(portsからnodePortを消すのを忘れずに)。これで、LoadBalancerが作られる。

無事LoadBalancerが作られると、以下のようにfront-end ServiceのTYPEがLoadBlancerとなり、EXTERNAL-IPにLoadBalancerが使うFloatingIPのIPアドレスが割り振られる。このアドレスにブラウザでアクセスすると、microservices-demoのショップ画面を見ることができる。

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

carts ClusterIP 10.233.45.134 <none> 80/TCP 20m

carts-db ClusterIP 10.233.1.15 <none> 27017/TCP 20m

catalogue ClusterIP 10.233.18.173 <none> 80/TCP 20m

catalogue-db ClusterIP 10.233.54.204 <none> 3306/TCP 20m

front-end LoadBalancer 10.233.5.150 XXX.XXX.XXX.XXX 80:31133/TCP 19m

orders ClusterIP 10.233.13.160 <none> 80/TCP 19m

orders-db ClusterIP 10.233.46.106 <none> 27017/TCP 19m

payment ClusterIP 10.233.1.219 <none> 80/TCP 19m

queue-master ClusterIP 10.233.3.45 <none> 80/TCP 19m

rabbitmq ClusterIP 10.233.9.44 <none> 5672/TCP 19m

shipping ClusterIP 10.233.43.87 <none> 80/TCP 19m

user ClusterIP 10.233.44.200 <none> 80/TCP 19m

user-db ClusterIP 10.233.3.11 <none> 27017/TCP 19m

このとき、インターネットからコンテナへの経路は以下のようになるはず。

front-end Serviceの詳細も見ておこう。とはいっても特別見る点はないが。

Name: front-end

Namespace: sock-shop

Labels: name=front-end

Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"name":"front-end"},"name":"front-end","namespace":"sock-shop"},"spec":{"por...

Selector: name=front-end

Type: LoadBalancer

IP: 10.233.5.150

LoadBalancer Ingress: XXX.XXX.XXX.XXX

Port: <unset> 80/TCP

TargetPort: 8079/TCP

NodePort: <unset> 31133/TCP

Endpoints: 10.233.101.142:8079

Session Affinity: None

External Traffic Policy: Cluster

Events:

  Type Reason Age From Message

  ---- ------ ---- ---- -------

  Normal EnsuringLoadBalancer 20m service-controller Ensuring load balancer

  Normal EnsuredLoadBalancer 18m service-controller Ensured load balancer

Octaviaによって作られたLoadBalancer自体を確認しておく。名前が分かりにくい…(当然だが、各idはダミー)

+---------------------+--------------------------------------------------------------+

| Field | Value |

+---------------------+--------------------------------------------------------------+

| admin_state_up | True |

| created_at | 2018-02-06T08:52:21 |

| description | Kubernetes external service a0a62264f0b1b11e8b5a7fa163ec99b5 |

| flavor | |

| id | b231e712-59b2-4d11-8243-a801c4d532b2 |

| listeners | 9bb69e7e-7901-4137-93db-8fca651fe13b |

| name | a0a62264f0b1b11e8b5a7fa163ec99b5 |

| operating_status | OFFLINE |

| pools | 1e1be81f-8cf6-4043-8c47-59020d9fba1b |

| project_id | 4b7dea695f3f4b7abcd4175dd6464783 |

| provider | octavia |

| provisioning_status | ACTIVE |

| updated_at | 2018-02-06T08:53:33 |

| vip_Address | YYY.YYY.YYY.YYY |

| vip_network_id | 1574d358-0f43-4c27-9004-f6be31be92eb |

| vip_port_id | 4f2d5855-3630-4139-bf33-1a2d520f256e |

| vip_subnet_id | 1351ff61-368e-48a9-9e90-dd39840a583f |

+---------------------+--------------------------------------------------------------+

このLoadBalancerや関連リソース(listener、pool、member)はKubernetes側でリソースを消すと自動的に削除されるので便利である。

なお、デフォルトではマニフェストで許可したポートについて、0.0.0.0/0からのアクセスを許可した状態となっている。要件によってはここを制限したくなることがあると思うが、これをマニフェストから設定できるのかは今後調査したい。さらには、Kubernetes on AWS: LoadBalancer型 Service との決別のように、LoadBalancerをTerraformで作成してKubernetesと繋ぐという手段も考えられるので、そちらも検証したいところである。