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と繋ぐという手段も考えられるので、そちらも検証したいところである。