背景
エッジクラウドのシナリオで、K8s を各地に分散していくアーキテクチャがよくあります。
例えば全国の各店舗にエッジを置いて、試着の AR を動かしたり、各地工場にエッジを置いて IoT シスエムを動かしたりするケースが考えられます。
K8s cluster が複数に分散されますが、それぞれの店舗、工場に IT 人員を配置することはもちろん不可能ですが、たとえすべてリモートで接続できるとして、数百個の Cluster に対して一々 kubectl を打ったりするのも非現実的です。
もちろんスクリプトやAnsible/Jenkinsを組めば、自動的に回すことができますが、例えばやりたいことはすべてのクラスタに対して同じコマンドを打つのだけではなくて、地域によって、クラスタをグルーピングして、特定のグループに対して特定な操作を一斉にしたい場合ならば、状況が複雑になります。これで、大量の同質な K8s cluster をどう管理運用していけばよいかが課題となります。
Kubefed
Kubefed の全称は Kubernetes Cluster Federation であり、マルチクラスタを束ねて(Federation)、一つの K8s CRD resource として定義し、管理運用していく OSS ツールです。
Kubefed の Git Page
Kubefed の定義
下図のように、Kubefed は Master Cluster の kube-federation-system Namespace にインストールされます。そして、Master Cluster と Slave Cluster を Federation に Join させることによって Federation が構成できます。
kubefedctl join master --cluster-context cluster-1 --host-cluster-context cluster-1 --v=2
Kubefedctl join slave --cluster-context cluster-2 --host-cluster-context cluster-1 --v=2
kubectl -n kube-federation-system get kubefedclusters
NAME READY AGE
master True 1m
slave True 1m
これで、Master cluster に KubeFed 用の CRD リソースをデプロイすることで、対応するAPI リソースが Slave cluster にも自動的にデプロイされます。
対応している API リソースは以下の10種類:
federatedclusterroles federatednamespaces
federatedconfigmaps federatedreplicasets
federateddeployments federatedsecrets
federatedingresses federatedserviceaccounts
federatedjobs federatedservices
各種 CRD を使用する前に、Enable は必要となります。
kubefedctl enable <kind.api> --kubefed-namespace <NAMESPACE_INSTALL_KUBEFED> kube-federation-system
リソースのデプロイ
リソースをデプロイする前に、各クラスタ間で共通の Namespace (Federated Namespace)を作ることが必要です。
KubeFed は Federated Namespace のみに対して操作可能です。
手順として、まずは Master Cluster 上で普通の Namespace を作成します。
kubectl create ns stars
そして、この Master Cluster 上で作成した Namespace をもとに、FederatedNamespace を作ります。
##On the master##
apiVersion: types.kubefed.io/v1beta1
kind: FederatedNamespace
metadata:
name: stars #<= must be identical to the kubernetes namespace you created with kubectl
namespace: stars #<= same
spec:
placement:
clusters:
- name: <REPLACE_ME> #Replace this with the name of your master's context name
- name: <REPLACE_ME> #Replace this with the name of your slave's context name
- name: … #If you have more slaves then add more elements
これを deploy すると、指定された Slave Cluster 内で Master Cluster と同じ Namespace が Kubefed によって自動的に作成されます。
そして、各種 API リソースに対応する CRD(例:FederatedDeployment)の yaml を定義してデプロイします。
##On the master##
apiVersion: types.kubefed.io/v1beta1
kind: FederatedDeployment
metadata:
name: federated-xwings
namespace: stars
spec:
template:
metadata:
name: xwings
spec:
... # Normal deployment spec
placement:
clusters:
- name: master
- name: slave
overrides:
- clusterName: master
clusterOverrides:
- path: "/spec/replicas"
value: 2
spec は通常の deployment yaml に従って書けばよいです。
面白いのは Placement と overrides のセクションです。Placement は配置先の Cluster を定義します。Overrides は各配置先ごとに spec をカスタマイズ可能とします。なので、単純な同質デプロイだけではなく、スコープをコントロールしたり、カスタマイズが可能です。
さらにいうと、kubefeded cluster にラベルつけて、ラベルベースでの placement ルールを書くことも可能です。
kubectl label kubefedclusters -n kube-federation-system cluster1 foo=bar
spec:
placement:
clusterSelector:
matchLabels:
foo: bar
その他機能
幾つかのトラブルシューティングの機能も用意されています。
・Federated Cluster 確認
kubectl -n kube-federation-system get kubefedclusters
・Federated リソース 確認
kubectl describe federateddeployments test-deployment –n test-ns
・Kubefed log 確認
kubectl logs deployment/kubefed-controller-manager -n kube-federation-system
さらにより新しめの機能として、マルチクラスタ間で Replica Set を重み付けてリソース分散配置する機能も開発されました。
apiVersion: scheduling.kubefed.io/v1alpha1
kind: ReplicaSchedulingPreference
metadata:
name: test-deployment
namespace: test-ns
spec:
targetKind: FederatedDeployment
totalReplicas: 9
rebalance: true
clusters:
A:
minReplicas: 4
maxReplicas: 6
weight: 1
B:
minReplicas: 4
maxReplicas: 8
weight: 2
これでより柔軟にマルチクラスタ間のワークロード配置が便利に実現できるようになります。
Replica Scheduling の Git page
最後に
KubeFed 自体は OSS ツールであり、スケールや安定性などの問題は多々ありますが、冒頭で議論した通リ、マルチクラスタ統合運用のニーズはエッジの普及により段々上がっていきますので、参考の選択肢として KubeFed は非常にいい機能(placement, overrides, replaca scheduling)を実現し、いいヒントをくれています。