はじめに
NTTコミュニケーションズ Advent Calendar 2020の5日目を担当します@khrdです!
本記事は自チームで運用中のk8sクラスタについて,今後どうやってテナントを切り出していけば社内ユーザにとって使いやすいだろう,自チームで管理しやすいだろうといった文脈からMulti-Tenancy sigで取り組まれているプロジェクトの1つであるVirtual Clusters
(以下VC
と省略)について調査をまとめたものになります.
目次
この記事で触れる内容は下記の通りで,上から順番に説明を進めてさせていただきます.
- VCの概要
- VCの作成手順
- スーパークラスタ(親クラスタ)とテナントクラスタ(VC)で見える範囲の違い
- VCでAdmin操作をしてみる
- まとめ
VCの概要
VCは一言で言ってしまえば,スーパークラスタ(親クラスタ)の中に仮想的なクラスタ(VC)を作成できる仕組みです.
スーパークラスタの中にVC専用のapiserverやetcdを作成するため,テナントユーザはVCを強い権限で操作することができ,他のテナントやスーパークラスタを直接見たり操作することができないため強固なアイソレーションを実現できます.
こちらによると主要なコンポーネントは3つあり,vc-manager
, syncer
, vn-agent
があり役割はそれぞれ下記のとおりです.
1. vc-manager
VCクラスタの管理を担当.VCのCRDの変更をウォッチして望ましい状態にする.
2. syncer
VCとスーパークラスタ間を同期を担当.VCユーザがVCのネームスペース配下にPodを作成するとスーパークラスタに反映させる.その逆もしかり.
3. vn-agent
Superクラスタのkubeletにプロキシする. kubeletとやりとりを行うのでdaemonSetリソースで全Workerノードに配置される.
Pros/Cons
Pros
- VCユーザ(テナントクラスタのユーザ)はRBAC操作やCRDのインストールなどcluster admin権限でVCを操作することができる
- VCユーザは他のVCやスーパークラスタのPodやNamespaceを見れない(アイソレーションができる)
Cons
-
スーパークラスタとVCのクラスタVersionは同じであることが推奨
- 現時点でv1.16でSyncerはビルドされているため後方互換性はサポートされない...
-
VCはPVをサポートしておらず,スーパークラスタのPVを利用する形となる
- こちらは大きなデメリットとはならなさそうですが,テナントユーザが各自のStorageを利用したい場合には問題になるかもしれません
-
VCのCNIはテナントユーザがカスタマイズできない
-
VCユーザがVCの証明書をローテートする方法が用意されていない
- スーパクラスター管理者でないと実施できなさそう
VCの作成手順
今回用意するテスト環境
テスト環境として上記のようなクラスタをKindで作成します
- Kind Test cluster
- master x1台
- worker x3台
- Cluster versionは1.16.15
- ホスト端末はMac book pro
こちらのクラスタ内にVCのCRDなどををインストールしていき作成のテナントクラスタの作成を行っていきます.
vcサブコマンドをMacにインストール
まずVC作成にあたってkubectlプラグインであるvc
をのちのち使用しますが,
バイナリが提供されていないため先にこちらをビルドして準備します.
使用したGoのバージョンは下記の通りです
$ go version
go version go1.13.4 darwin/amd64
リポジトリからソースファイルなどを取得してビルドします
$ go get github.com/kubernetes-sigs/multi-tenancy
$ make build WHAT=cmd/kubectl-vc GOOS=darwin
$ sudo cp _output/bin/kubectl-vc /usr/local/bin
プラグインインストールが完了すると下記のようなvc
サブコマンドが使用可能となります
$ kubectl vc --version
kubectl-vc version v1.0.0-3dc7a9c
Kindでテストクラスタを構築する
それではKindでテスト環境を作っていきます
master
x1, worker
x3のマルチクラスターを構成するためにmultinode.yaml
を作成します.
$ cat << EOF > multinode.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
- role: worker
EOF
作成したmutinode.yaml
を用いてスーパークラスタを作成します
$ kind create cluster --config multinode.yaml --image=kindest/node:v1.16.15
Creating cluster "kind" ...
✓ Ensuring node image (kindest/node:v1.16.15) 🖼
✓ Preparing nodes 📦 📦 📦 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
✓ Joining worker nodes 🚜
Set kubectl context to "kind-kind"
You can now use your cluster with:
kubectl cluster-info --context kind-kind
Have a nice day! 👋
VCのCRDなどの適用
続いてVCのインストールを行います
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/multi-tenancy/master/incubator/virtualcluster/config/crds/tenancy.x-k8s.io_clusterversions.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/multi-tenancy/master/incubator/virtualcluster/config/crds/tenancy.x-k8s.io_virtualclusters.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/multi-tenancy/master/incubator/virtualcluster/config/setup/all_in_one.yaml
インストールした時点でvc-manager
namespaceに概要で述べたcomponentsがインストールされます.
Cluster Versionの適用
次にVCの雛形となるCluster Versionと呼ばれるCRDリソースを適用します.
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/multi-tenancy/master/incubator/virtualcluster/config/sampleswithspec/clusterversion_v1_nodeport.yaml
ちなみにClusterVersionの中身はこのようになっています.
VCのクラスターのマスター機能であるetcdやapiserverのimage, 実行時の引数などが記述されています.
なおデメリットでも述べたとおり,vn-agentなどが1.16でビルドされているため,使われているimageを最新versionにするなど柔軟には変えられそうにないです...
apiVersion: tenancy.x-k8s.io/v1alpha1
kind: ClusterVersion
metadata:
labels:
controller-tools.k8s.io: "1.0"
name: cv-sample-np
spec:
etcd:
~~省略~~
spec:
subdomain: etcd
containers:
- name: etcd
image: virtualcluster/etcd-v3.4.0
~~省略~~
apiserver:
~~省略~~
spec:
hostname: apiserver
subdomain: apiserver-svc
containers:
- name: apiserver
image: virtualcluster/apiserver-v1.16.2
imagePullPolicy: Always
~~省略~~
controllerManager:
~~省略~~
spec:
containers:
- name: controller-manager
image: virtualcluster/controller-manager-v1.16.2
imagePullPolicy: Always
~~省略~~
VCの作成
最後にvc
サブコマンドを利用してVirtualClusterリソースを作成することてVCが作成されます.
$ kubectl vc create -f https://raw.githubusercontent.com/kubernetes-sigs/multi-tenancy/master/incubator/virtualcluster/config/sampleswithspec/virtualcluster_1_nodeport.yaml -o vc-1.kubeconfig
2020/10/22 13:34:24 etcd is ready
2020/10/22 13:34:45 apiserver is ready
2020/10/22 13:35:19 controller-manager is ready
2020/10/22 13:35:19 VirtualCluster default/vc-sample-1 setup successfully
コマンド実行終了するとVCユーザ用のkubeconfigvc-1.kubeconfig
が生成されます.
##スーパークラスタとテナントクラスタ(VC)で見える範囲の違い
さてvcが作成できたので早速アイソレーションができているか確認してみましょう.
スーパークラスタからの見え方
Namespace
まずNamespaceを確認します
$ k get ns
NAME STATUS AGE
default Active 91m
default-b41df0-vc-sample-1 Active 34m
default-b41df0-vc-sample-1-default Active 33m
default-b41df0-vc-sample-1-kube-node-lease Active 33m
default-b41df0-vc-sample-1-kube-public Active 33m
default-b41df0-vc-sample-1-kube-system Active 33m
kube-node-lease Active 91m
kube-public Active 91m
kube-system Active 91m
local-path-storage Active 91m
vc-manager Active 74m
こちらのとおり,default-b41df0-vc-sample-1*
というNamespaceリソースが生成されされており
すべて1つのVC用のNamespaceリソースとなっています.
ちなみにVCのマスター機能はdefault-b41df0-vc-sample-1
Namespaceで動作しています.
$ k get statefulsets.apps -n default-b41df0-vc-sample-1
NAME READY AGE
apiserver 1/1 35m
controller-manager 1/1 35m
etcd 1/1 35m
テナントクラスタからの見え方
Namespace
VCからNamespaceを確認します
$ k get ns
NAME STATUS AGE
default Active 7m4s
kube-node-lease Active 7m6s
kube-public Active 7m6s
kube-system Active 7m6s
ご覧の通り,スーパクラスターからは全てのNamespaceが閲覧できましたが,VCからはVC用のNamespaceしか見れなくなりました.
またスーパクラスターではVC用のNamespaceはdefault-b41df0-vc-sample-1-*
という名前になっていましたが,
VCから見ると下図のようにdefault-b41df0-vc-sample-1-
以下の名前として表示されます.
Node
VCからノード確認ができるか確認してみました.
$ k get no
No resources found
どうやらVCからノード情報は見れないようです.
VCでAdmin操作をしてみる
最後にVCはテナントユーザが強い権限を使うことが可能なのでAdmin操作可能かどうかを見てみます
RBAC
$ k apply -f my-role.yaml
role.rbac.authorization.k8s.io/my-role created
$ kubectl apply -f my-rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/my-rolebinding created
RBAC操作は問題なく行えました
CRD
$ k apply -f https://github.com/jetstack/cert-manager/releases/download/v1.1.0/cert-manager.yaml
customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created
~~省略~~
CRDのインストールも問題なく行えました
クラスタ管理者に代理でインストールや強い権限を付与してもらわなくてもテナントユーザが自由にクラスタをいじれそうなので便利そうです
まとめ
まとめです.
VirtualClusterの基本的なコンポーネントを確認した後,実際にインストールして強力なアイソレーションが出来ていることを確認できました.
ただConsでも述べた通り,テナントユーザが操作できない領域もあり,その辺りの改善が今後されるかどうか注視したいと思います.
また,今回紹介できなかったmulti-tenancy sigの別プロジェクトである「Tenant Operator」「Hierararchical namespaces (aka HNC)」についても今後の動きに期待ですね!
明日は,@staybuzzさんの投稿です.お楽しみに!!
参考資料
https://github.com/kubernetes-sigs/multi-tenancy/tree/master/incubator/virtualcluster
https://www.youtube.com/watch?v=5RgF_dYyvEY