はじめに
Tanzu Community Edition(TCE)Antrea Multi-clusterを試してみました。Antrea Multi-clusterはKEP-1645: Multi-Cluster Services APIに対するAntreaの実装です。
Antrea Multi-clusterのアーキテクチャ
Antrea Multi-clusterはLeaderクラスターとMemberクラスターで構成され、Memberクラスターで作成されたServiceリソースに対してServiceExportを作成すると、LeaderクラスターにServiceリソースがExportされ、他のMemberクラスターはLeaderクラスターにExportされたServiceリソースをImportします。LeaderクラスターはMemberと併用可能ですが、必ず一つのクラスターがLeaderとして機能する必要があります。(参考 : Antrea Multi-cluster Architecture)
TCEクラスターの作成
TCE v0.11.0に含まれるAntreaはv1.2.3ですが、Antrea Multi-clusterはv1.5.0からサポートされた機能であるためTCEがインストールするAntreaの環境では利用できません。今回は最新のAntrea v1.6.0を利用するため、TCEクラスター作成時のCNI構成を無効化し、手動でAntreaをインストールします。また、現在のMulti-cluster機能は各クラスター間のServiceリソースの同期のみ行い、データプレーンには関与しません。クラスターを跨るPod間通信を可能にするため、Antreaのカプセル化とSNAT機能を無効化しRoutable Pod構成として以下のような3つのTCEクラスターを作成し、cl1をLeader専用、cl2/cl3をMemberとして構成します。
TCEで3つのクラスターを作成します。TCEクラスター作成時のCNIの構成を無効化するためにCNI=none
として、各クラスターには異なるAPIのIPアドレス(VSPHERE_CONTROL_PLANE_ENDPOINT
)と、Pod/Service向けCIDR(CLUSTER_CIDR
、SERVICE_CIDR
)を割り当てます。
CNI=none VSPHERE_CONTROL_PLANE_ENDPOINT=192.168.201.104 CLUSTER_CIDR=172.16.0.0/21 SERVICE_CIDR=172.16.64.0/21 tanzu cl create cl1 -f tce.yaml
クラスターの作成が開始され、CNIの構成が完了しないためクラスターの作成がWaiting状態になります。
Validating configuration...
Creating workload cluster 'cl1'...
Waiting for cluster to be initialized...
cluster control plane is still being initialized: WaitingForControlPlane
cluster control plane is still being initialized: Cloning @ Machine/cl1-control-plane-kwmvx
cluster control plane is still being initialized: PoweringOn @ Machine/cl1-control-plane-kwmvx
Waiting for cluster nodes to be available...
Waiting for addons installation...
Waiting for packages to be up and running...
tanzu CLIで確認すると、creating
状態となっています。(このまましばらく放置するとtancu cl create
コマンドはタイムアウトで終了し、createStalled
という状態になりますが、CNIを正しく設定することでクラスターはrunning
状態となり正常に機能します。)
$ tanzu cl list
NAME NAMESPACE STATUS CONTROLPLANE WORKERS KUBERNETES ROLES PLAN
cl1 default creating 0/1 1/1 v1.22.8+vmware.1 <none> dev
作成中のクラスターにCNIを手動でインストールするため、tanzu CLIでクラスターのクレデンシャルを取得して、接続先として設定します。
$ tanzu cl kubeconfig get cl1 --admin
Credentials of cluster 'cl1' have been saved
You can now access the cluster by running 'kubectl config use-context cl1-admin@cl1'
$ kubectl config use-context cl1-admin@cl1
クラスターのノードの状態を確認すると、NotReady
状態となっています。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
cl1-control-plane-9thmg NotReady control-plane,master 49s v1.22.8+vmware.1
$ kubectl get node
NAME STATUS ROLES AGE VERSION
cl1-control-plane-9thmg NotReady control-plane,master 57s v1.22.8+vmware.1
cl1-md-0-7c57d8d6d4-cbbj9 NotReady <none> 4s v1.22.8+vmware.1
Podの状態を確認するとcorednsがPending
状態となっています。
$ kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-67c8559bb6-89hmw 0/1 Pending 0 51s
kube-system coredns-67c8559bb6-x9fbg 0/1 Pending 0 51s
kube-system etcd-cl1-control-plane-9thmg 1/1 Running 0 59s
kube-system kube-apiserver-cl1-control-plane-9thmg 1/1 Running 0 58s
kube-system kube-controller-manager-cl1-control-plane-9thmg 1/1 Running 0 59s
kube-system kube-proxy-94l4n 1/1 Running 0 14s
kube-system kube-proxy-cnd49 1/1 Running 0 52s
kube-system kube-scheduler-cl1-control-plane-9thmg 1/1 Running 0 59s
kube-system kube-vip-cl1-control-plane-9thmg 1/1 Running 0 66s
tkg-system kapp-controller-6ccc86f49f-9l8gk 1/1 Running 0 34s
tkg-system tanzu-capabilities-controller-manager-798c4d557c-pw46l 0/1 Pending 0 51s
ノードのIPアドレスと各ノードのpodCIDR
を確認して、ルータにスタティックルートを追加します。
$ kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
cl1-control-plane-9thmg NotReady control-plane,master 87s v1.22.8+vmware.1 192.168.201.63 <none> VMware Photon OS/Linux 4.19.232-2.ph3 containerd://1.5.9
cl1-md-0-7c57d8d6d4-cbbj9 NotReady <none> 34s v1.22.8+vmware.1 192.168.201.8 <none> VMware Photon OS/Linux 4.19.232-2.ph3 containerd://1.5.9
$ kubectl get node -o=jsonpath='{range .items[*]}{.spec.podCIDR}{"\n"}{end}'
172.16.0.0/24
172.16.1.0/24
antreaをインストールするためのマニフェストのantrea-config ConfigMapのantrea-agent.conf
に含まれるtrafficEncapMode
をnoEncap
、noSNAT
をtrue
として設定し、Podのすべての通信をEncap/SNATしないように設定します。
--- antrea.yml.org 2022-03-29 16:57:20.000000000 +0000
+++ antrea.yml 2022-05-09 00:01:39.071536349 +0000
@@ -2811,14 +2811,14 @@
# networkPolicyOnly: Antrea enforces NetworkPolicy only, and utilizes CNI chaining and delegates Pod
# IPAM and connectivity to the primary CNI.
#
- #trafficEncapMode: encap
+ trafficEncapMode: noEncap
# Whether or not to SNAT (using the Node IP) the egress traffic from a Pod to the external network.
# This option is for the noEncap traffic mode only, and the default value is false. In the noEncap
# mode, if the cluster's Pod CIDR is reachable from the external network, then the Pod traffic to
# the external network needs not be SNAT'd. In the networkPolicyOnly mode, antrea-agent never
# performs SNAT and this option will be ignored; for other modes it must be set to false.
- #noSNAT: false
+ noSNAT: true
# Tunnel protocols used for encapsulating traffic across Nodes. If WireGuard is enabled in trafficEncryptionMode,
# this option will not take effect. Supported values:
変更したマニフェストをapplyしてCNIを構成します。
$ kubectl apply -f antrea.yaml
しばらくすると、antreaが有効になり、corednsがRunning状態となります。
$ kubectl get po -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system antrea-agent-vhvmv 2/2 Running 0 40s
kube-system antrea-agent-wfhls 2/2 Running 0 40s
kube-system antrea-controller-6b69877d5c-9qxh4 1/1 Running 0 40s
kube-system coredns-67c8559bb6-8l5z9 1/1 Running 0 3m4s
kube-system coredns-67c8559bb6-m69fg 1/1 Running 0 3m4s
kube-system etcd-cl1-control-plane-9thmg 1/1 Running 0 3m12s
kube-system kube-apiserver-cl1-control-plane-9thmg 1/1 Running 0 3m11s
kube-system kube-controller-manager-cl1-control-plane-9thmg 1/1 Running 0 3m12s
kube-system kube-proxy-66gpx 1/1 Running 0 2m27s
kube-system kube-proxy-fg79m 1/1 Running 0 3m5s
kube-system kube-scheduler-cl1-control-plane-9thmg 1/1 Running 0 3m12s
kube-system kube-vip-cl1-control-plane-9thmg 1/1 Running 0 3m19s
kube-system metrics-server-5766bd59cb-jv6gs 1/1 Running 0 49s
kube-system vsphere-cloud-controller-manager-t2b58 1/1 Running 0 76s
kube-system vsphere-csi-controller-5c4c85bbff-6rjkr 6/6 Running 0 47s
kube-system vsphere-csi-node-qmdm2 3/3 Running 2 (23s ago) 47s
kube-system vsphere-csi-node-wvwfg 3/3 Running 2 (24s ago) 47s
tanzu-system secretgen-controller-555567956c-bkcj7 1/1 Running 0 75s
tkg-system kapp-controller-55fb69d57d-gxk4k 1/1 Running 0 2m47s
tkg-system tanzu-capabilities-controller-manager-798c4d557c-bpqqp 1/1 Running 0 3m4s
同じ手順で2つのクラスターを追加して、各クラスターでCNIを構成します。
CNI=none VSPHERE_CONTROL_PLANE_ENDPOINT=192.168.201.105 CLUSTER_CIDR=172.16.8.0/21 SERVICE_CIDR=172.16.72.0/21 tanzu cl create cl2 -f tce.yaml
CNI=none VSPHERE_CONTROL_PLANE_ENDPOINT=192.168.201.106 CLUSTER_CIDR=172.16.16.0/21 SERVICE_CIDR=172.16.80.0/21 tanzu cl create cl3 -f tce.yaml
作成した3つのクラスターのkubeconfigをファイルに出力します。
tanzu cl kubeconfig get cl1 --admin --export-file cl1.yaml
tanzu cl kubeconfig get cl2 --admin --export-file cl2.yaml
tanzu cl kubeconfig get cl3 --admin --export-file cl3.yaml
Leaderの設定
Leaderクラスターに対してLeader向けのCRDを作成します。
$ kubectl --kubeconfig=cl1.yaml apply -f https://github.com/antrea-io/antrea/releases/download/v1.6.0/antrea-multicluster-leader-global.yml
customresourcedefinition.apiextensions.k8s.io/clusterclaims.multicluster.crd.antrea.io created
customresourcedefinition.apiextensions.k8s.io/clustersets.multicluster.crd.antrea.io created
customresourcedefinition.apiextensions.k8s.io/memberclusterannounces.multicluster.crd.antrea.io created
customresourcedefinition.apiextensions.k8s.io/resourceexportfilters.multicluster.crd.antrea.io created
customresourcedefinition.apiextensions.k8s.io/resourceexports.multicluster.crd.antrea.io created
customresourcedefinition.apiextensions.k8s.io/resourceimportfilters.multicluster.crd.antrea.io created
customresourcedefinition.apiextensions.k8s.io/resourceimports.multicluster.crd.antrea.io created
Common Areaとなるantrea-mcs-ns
ネームスペースを作成し、Leaderに必要なコンポーネントをデプロイします。Leader上のController(deployment.apps/antrea-mc-controller
)はantrea-mcs-ns
ネームスペースで起動します。githubで公開されているマニフェストではNamespaceがchangeme
となっているため、Common Areaとして利用するNamespace名(antrea-mcs-ns
)に置換する必要があります。
$ kubectl --kubeconfig=cl1.yaml create ns antrea-mcs-ns
$ curl -L https://github.com/antrea-io/antrea/releases/download/v1.6.0/antrea-multicluster-leader-namespaced.yml > antrea-multicluster-leader-namespaced.yml
$ sed 's/changeme/antrea-mcs-ns/g' antrea-multicluster-leader-namespaced.yml | kubectl --kubeconfig=cl1 apply -f -
serviceaccount/antrea-mc-controller created
serviceaccount/antrea-mc-member-access-sa created
role.rbac.authorization.k8s.io/antrea-mc-controller-role created
role.rbac.authorization.k8s.io/antrea-mc-member-cluster-role created
clusterrole.rbac.authorization.k8s.io/antrea-mcs-ns-antrea-mc-controller-webhook-role created
rolebinding.rbac.authorization.k8s.io/antrea-mc-controller-rolebinding created
rolebinding.rbac.authorization.k8s.io/antrea-mc-member-cluster-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/antrea-mcs-ns-antrea-mc-controller-webhook-rolebinding created
configmap/antrea-mc-controller-config-49875k4ht8 created
service/antrea-mc-webhook-service created
deployment.apps/antrea-mc-controller created
mutatingwebhookconfiguration.admissionregistration.k8s.io/antrea-mcs-ns-antrea-mc-mutating-webhook-configuration created
validatingwebhookconfiguration.admissionregistration.k8s.io/antrea-mcs-ns-antrea-mc-validating-webhook-configuration created
Member(cl2)がLeaderにアクセスする際にに利用するServiceAccountをLeaderクラスターのantrea-mcs-nsに作成します。
cat <<EOF | kubectl --kubeconfig=cl1.yaml apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: member-cl2-access-sa
namespace: antrea-mcs-ns
---
apiVersion: v1
kind: Secret
metadata:
name: member-cl2-access-token
namespace: antrea-mcs-ns
annotations:
kubernetes.io/service-account.name: member-cl2-access-sa
type: kubernetes.io/service-account-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: member-cl2-access-rolebinding
namespace: antrea-mcs-ns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: antrea-mc-member-cluster-role
subjects:
- kind: ServiceAccount
name: member-cl2-access-sa
namespace: antrea-mcs-ns
EOF
Member(cl3)がLeaderにアクセスする際にに利用するServiceAccountをLeaderクラスターのantrea-mcs-nsに作成します。
cat <<EOF | kubectl --kubeconfig=cl1.yaml apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: member-cl3-access-sa
namespace: antrea-mcs-ns
---
apiVersion: v1
kind: Secret
metadata:
name: member-cl3-access-token
namespace: antrea-mcs-ns
annotations:
kubernetes.io/service-account.name: member-cl3-access-sa
type: kubernetes.io/service-account-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: member-cl3-access-rolebinding
namespace: antrea-mcs-ns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: antrea-mc-member-cluster-role
subjects:
- kind: ServiceAccount
name: member-cl3-access-sa
namespace: antrea-mcs-ns
EOF
作成したServiceAccountの証明書とTokenをSecretをMemberのSecretとして利用できるようマニフェストを作成します。
kubectl --kubeconfig=cl1.yaml get secret member-cl2-access-token -n antrea-mcs-ns -o yaml | grep -w -e '^apiVersion' -e '^data' -e '^metadata' -e '^ *name:' -e '^kind' -e ' ca.crt' -e ' token:' -e '^type' -e ' namespace' | sed -e 's/kubernetes.io\/service-account-token/Opaque/g' -e 's/antrea-mcs-ns/kube-system/g' > cl2-token.yaml
kubectl --kubeconfig=cl1.yaml get secret member-cl3-access-token -n antrea-mcs-ns -o yaml | grep -w -e '^apiVersion' -e '^data' -e '^metadata' -e '^ *name:' -e '^kind' -e ' ca.crt' -e ' token:' -e '^type' -e ' namespace' | sed -e 's/kubernetes.io\/service-account-token/Opaque/g' -e 's/antrea-mcs-ns/kube-system/g' > cl3-token.yaml
LeaderにClusterSetリソースを定義します。Memberとしてcl2とcl3を設定します。
cat <<EOF | kubectl --kubeconfig cl1.yaml apply -f -
apiVersion: multicluster.crd.antrea.io/v1alpha1
kind: ClusterSet
metadata:
name: test-clusterset
namespace: antrea-mcs-ns
spec:
leaders:
- clusterID: test-cluster-cl1
members:
- clusterID: test-cluster-cl2
serviceAccount: "member-cl2-access-sa"
- clusterID: test-cluster-cl3
serviceAccount: "member-cl3-access-sa"
namespace: antrea-mcs-ns
EOF
Memberの設定
Memberクラスター(cl2)でMulti-cluster CRDを作成しControllerを起動します。Controller(deployment.apps/antrea-mc-controller
はkube-systemネームスペースで起動します。)
$ kubectl --kubeconfig=cl2.yaml apply -f https://github.com/antrea-io/antrea/releases/download/v1.6.0/antrea-multicluster-member.yml
customresourcedefinition.apiextensions.k8s.io/clusterclaims.multicluster.crd.antrea.io created
customresourcedefinition.apiextensions.k8s.io/clustersets.multicluster.crd.antrea.io created
customresourcedefinition.apiextensions.k8s.io/resourceexportfilters.multicluster.crd.antrea.io created
customresourcedefinition.apiextensions.k8s.io/resourceimportfilters.multicluster.crd.antrea.io created
customresourcedefinition.apiextensions.k8s.io/serviceexports.multicluster.x-k8s.io created
customresourcedefinition.apiextensions.k8s.io/serviceimports.multicluster.x-k8s.io created
serviceaccount/antrea-mc-controller created
clusterrole.rbac.authorization.k8s.io/antrea-mc-controller-role created
clusterrolebinding.rbac.authorization.k8s.io/antrea-mc-controller-rolebinding created
configmap/antrea-mc-controller-config-49875k4ht8 created
service/antrea-mc-webhook-service created
deployment.apps/antrea-mc-controller created
mutatingwebhookconfiguration.admissionregistration.k8s.io/antrea-mc-mutating-webhook-configuration created
validatingwebhookconfiguration.admissionregistration.k8s.io/antrea-mc-validating-webhook-configuration created
Leaderに作成したSerivceAccountでアクセスするための証明書とTokenをMember(cl2)にSecretとして作成します。
kubectl --kubeconfig=cl2 apply -f claim-cl2.yaml
Memberクラスター(cl2)にClusterClaim/ClusterSetリソースを作成します。ClsuterSetの.spec.leaders
にはLeaderのclusterID
としてcl1を指定し、server
としてcl1のAPIのアドレスを指定します。
cat <<EOF | kubectl --kubeconfig=cl2.yaml apply -f -
apiVersion: multicluster.crd.antrea.io/v1alpha1
kind: ClusterClaim
metadata:
name: cl2-membercluster-id
namespace: kube-system
name: id.k8s.io
value: test-cluster-cl2
---
apiVersion: multicluster.crd.antrea.io/v1alpha1
kind: ClusterClaim
metadata:
name: clusterset-id
namespace: kube-system
name: clusterSet.k8s.io
value: test-clusterset
---
apiVersion: multicluster.crd.antrea.io/v1alpha1
kind: ClusterSet
metadata:
name: test-clusterset
namespace: kube-system
spec:
leaders:
- clusterID: test-cluster-cl1
secret: "member-cl2-access-token"
server: "https://192.168.201.104:6443"
members:
- clusterID: test-cluster-cl2
namespace: antrea-mcs-ns
EOF
cl3でもおなじ様に、Multi-cluster CRDを作成しControllerを起動し、Leaderにアクセスするための証明書とTokenをSecretとして作成します。
kubectl --kubeconfig=cl3.yaml apply -f https://github.com/antrea-io/antrea/releases/download/v1.6.0/antrea-multicluster-member.yml
kubectl --kubeconfig=cl3.yaml apply -f claim-cl3.yaml
Memberクラスター(cl3)にClusterClaim/ClusterSetリソースを作成します。
cat <<EOF | kubectl --kubeconfig=cl3.yaml apply -f -
apiVersion: multicluster.crd.antrea.io/v1alpha1
kind: ClusterClaim
metadata:
name: cl3-membercluster-id
namespace: kube-system
name: id.k8s.io
value: test-cluster-cl3
---
apiVersion: multicluster.crd.antrea.io/v1alpha1
kind: ClusterClaim
metadata:
name: clusterset-id
namespace: kube-system
name: clusterSet.k8s.io
value: test-clusterset
---
apiVersion: multicluster.crd.antrea.io/v1alpha1
kind: ClusterSet
metadata:
name: test-clusterset
namespace: kube-system
spec:
leaders:
- clusterID: test-cluster-cl1
secret: "member-cl3-access-token"
server: "https://192.168.201.104:6443"
members:
- clusterID: test-cluster-cl3
namespace: antrea-mcs-ns
EOF
動作確認
クラスター間のService同期
cl2とcl3にdemoネームスペースを作成し、各ネームスペースにserver/client Deploymentを作成し、serverに対するServiceを作成します。
kubectl --kubeconfig=cl2.yaml create ns demo
kubectl --kubeconfig=cl2.yaml create deploy server --image=harbor.tce.example.com/library/demo:1.0 -n demo
kubectl --kubeconfig=cl2.yaml expose deploy/server --port=80 -n demo
cl2のdemoネームスペースでpodが起動して、serviceとendpointsが構成されています。
$ kubectl --kubeconfig=cl2.yaml get pod,svc,ep -o wide -n demo
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/server-6d9cc85c58-fkttn 1/1 Running 0 22s 172.16.9.21 cl2-md-0-8ffdf64f7-dpwlv <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/server ClusterIP 172.16.76.220 <none> 80/TCP 4m4s app=server
NAME ENDPOINTS AGE
endpoints/server 172.16.9.21:80 4m4s
cl3のdemoネームスペースにclient用のpodを作成します。
kubectl --kubeconfig=cl3.yaml create ns demo
kubectl --kubeconfig=cl3.yaml create deploy client --image=harbor.tce.example.com/library/demo:1.0 -n demo
cl3でclient podが起動します。serviceとendpointは存在しません。
$ kubectl --kubeconfig=cl3.yaml get pod,svc,ep -o wide -n demo
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/client-579678cd66-cwnfs 1/1 Running 0 2m23s 172.16.17.16 cl3-md-0-6f9c5f76db-8pghg <none> <none>
cl2でServiceExport
リソースを作成し、Service
cat <<EOF | kubectl --kubeconfig=cl2.yaml apply -f -
apiVersion: multicluster.x-k8s.io/v1alpha1
kind: ServiceExport
metadata:
name: server
namespace: demo
EOF
cl2にServiceExportリソースが作成されます。
kubectl --kubeconfig=cl2.yaml get serviceexport -n demo
NAME AGE
server 94s
cl2のSerivce/Endpontsリソースを確認するとantrea-mc-server
が追加されています。
$ kubectl --kubeconfig=cl2.yaml get svc,ep -n demo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/antrea-mc-server ClusterIP 172.16.79.15 <none> 80/TCP 4m8s
service/server ClusterIP 172.16.76.220 <none> 80/TCP 11m
NAME ENDPOINTS AGE
endpoints/antrea-mc-server <none> 4m8s
endpoints/server 172.16.9.21:80 11m
cl3のServiceリソースを確認するとantrea-mc-server
が追加されています。
$ kubectl --kubeconfig=cl3.yaml get svc,ep -n demo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/antrea-mc-server ClusterIP 172.16.83.110 <none> 80/TCP 4m52s
NAME ENDPOINTS AGE
endpoints/antrea-mc-server 172.16.9.21:80 4m52s
Leaderであるcl1にはResourceExport/ResourceImportリソースが作成されています。
$ kubectl --kubeconfig=cl1.yaml get resourceexport -n antrea-mcs-ns
NAME AGE
test-cluster-cl2-demo-server-endpoints 5m48s
test-cluster-cl2-demo-server-service 5m48s
$ kubectl --kubeconfig=cl1.yaml get resourceimport -n antrea-mcs-ns
NAME AGE
demo-server-endpoints 5m54s
demo-server-service 5m55s
cl3のclient podからcl3上にImportされた、cl2のService(antrea-mc-server)にアクセスすると、cl2上で起動するpod(172.16.9.21)が応答しています。
$ kubectl --kubeconfig=cl3.yaml exec -it -n demo client-579678cd66-cwnfs -- curl antrea-mc-server
Server address: 172.16.9.21:80
Server name: server-6d9cc85c58-fkttn
Date: 09/May/2022:13:35:26 +0000
URI: /
Request ID: bd68749472215d86fddd1db5c7ec1854
Serviceの更新
server podを1 > 3にスケールアウトして、ExportされるServiceに状態が反映されるかどうか確認してみます。
Pod数の増加に応じてローカルのEndpointsは更新されました。
$ kubectl --kubeconfig=cl2.yaml scale deploy server --replicas=3 -n demo
deployment.apps/server scaled
$ kubectl --kubeconfig=cl2.yaml get pod,svc,ep -n demo -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/server-6d9cc85c58-5qx9s 1/1 Running 0 64s 172.16.9.10 cl2-md-0-8ffdf64f7-dpwlv <none> <none>
pod/server-6d9cc85c58-dnn7t 1/1 Running 0 64s 172.16.9.11 cl2-md-0-8ffdf64f7-dpwlv <none> <none>
pod/server-6d9cc85c58-fkttn 1/1 Running 0 23m 172.16.9.21 cl2-md-0-8ffdf64f7-dpwlv <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/antrea-mc-server ClusterIP 172.16.79.15 <none> 80/TCP 19m <none>
service/server ClusterIP 172.16.76.220 <none> 80/TCP 27m app=server
NAME ENDPOINTS AGE
endpoints/antrea-mc-server <none> 19m
endpoints/server 172.16.9.10:80,172.16.9.11:80,172.16.9.21:80 27m
cl3にExportされたEndpointsもLeaderにより同期され、追加されたpodのIPアドレス(172.16.10.10, 172.16.10.11)が追加されています。
$ kubectl --kubeconfig=cl3.yaml get pod,svc,ep -n demo -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/client-579678cd66-cwnfs 1/1 Running 0 25m 172.16.17.16 cl3-md-0-6f9c5f76db-8pghg <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/antrea-mc-server ClusterIP 172.16.83.110 <none> 80/TCP 20m <none>
NAME ENDPOINTS AGE
endpoints/antrea-mc-server 172.16.9.10:80,172.16.9.11:80,172.16.9.21:80 20m
cl3のclient podからcl3上にImportされた、cl2のService(antrea-mc-server)にアクセスすると、cl2上で起動するpod(172.16.10.10, 172.16.10.11,172.16.9.21,)が応答しています。
$ kubectl --kubeconfig=cl3.yaml exec -it -n demo client-579678cd66-cwnfs -- curl antrea-mc-server
Server address: 172.16.9.10:80
Server name: server-6d9cc85c58-5qx9s
Date: 09/May/2022:13:49:19 +0000
URI: /
Request ID: ce5084d98b6a24ec8903b047d3f38742
$ kubectl --kubeconfig=cl3.yaml exec -it -n demo client-579678cd66-cwnfs -- curl antrea-mc-server
Server address: 172.16.9.21:80
Server name: server-6d9cc85c58-fkttn
Date: 09/May/2022:13:49:20 +0000
URI: /
Request ID: d747993da6b3db3bd1e71a000a11c3e0
$ kubectl --kubeconfig=cl3.yaml exec -it -n demo client-579678cd66-cwnfs -- curl antrea-mc-server
Server address: 172.16.9.11:80
Server name: server-6d9cc85c58-dnn7t
Date: 09/May/2022:13:49:22 +0000
URI: /
Request ID: 7c7b3d4cb86de00b6497f5925dbba128
Network Policyの同期
v1.6.0からAntrea ClusterNetworkPolicy(ACNP)の同期もサポートしています。LeaderにResourceExportとしてACNPリソースを作成します。(ネームスペース内の通信と、app: client2
というラベルが付いたpodからのみアクセスを許可するポリシーです。)
cat <<EOF | kubectl --kubeconfig=cl1.yaml apply -f -
apiVersion: multicluster.crd.antrea.io/v1alpha1
kind: ResourceExport
metadata:
name: strict-namespace-isolation-for-test-clusterset
namespace: antrea-mcs-ns
spec:
kind: AntreaClusterNetworkPolicy
name: strict-namespace-isolation
clusternetworkpolicy:
priority: 1
tier: securityops
appliedTo:
- namespaceSelector: {}
ingress:
- action: Pass
from:
- namespaces:
match: Self
- podSelector:
matchLabels:
app: client2
- action: Drop
from:
- namespaceSelector: {}
EOF
LeaderにResourceExportとResourceImportリソースが作成されます。
$ kubectl --kubeconfig=cl1.yaml get resourceexport -n antrea-mcs-ns
NAME AGE
strict-namespace-isolation-for-test-clusterset 23s
test-cluster-cl2-demo-server-endpoints 25m
test-cluster-cl2-demo-server-service 25m
$ kubectl --kubeconfig=cl1.yaml get resourceimport -n antrea-mcs-ns
NAME AGE
demo-server-endpoints 25m
demo-server-service 25m
strict-namespace-isolation-antreaclusternetworkpolicy 35s
MemberでACNPを確認すると、各クラスターにリソースが追加されています。
$ kubectl --kubeconfig=cl2.yaml get acnp
NAME TIER PRIORITY DESIRED NODES CURRENT NODES AGE
antrea-mc-strict-namespace-isolation securityops 1 2 2 48s
$ kubectl --kubeconfig=cl3.yaml get acnp
NAME TIER PRIORITY DESIRED NODES CURRENT NODES AGE
antrea-mc-strict-namespace-isolation securityops 1 2 2 50s
cl2とcl3にdemo2ネームスペースを作成し、それぞれのネームスペースにclient2/client3 deploymentを作成します。
kubectl --kubeconfig=cl2.yaml create ns demo2
kubectl --kubeconfig=cl2.yaml create deploy client2 --image=harbor.tce.example.com/library/demo:1.0 -n demo2
kubectl --kubeconfig=cl2.yaml create deploy client3 --image=harbor.tce.example.com/library/demo:1.0 -n demo2
cl2とcl3でclietn2/clietn3 podが起動します。
$ kubectl --kubeconfig=cl2.yaml get pod -n demo2
NAME READY STATUS RESTARTS AGE
client2-d95b6c978-zrcxf 1/1 Running 0 11s
client3-5f564bd4cc-6t57l 1/1 Running 0 10s
ACNPの制御によりcl2のclient2からはserverにアクセスができますが、client2からはアクセスすることができません。
$ kubectl --kubeconfig=cl2.yaml exec -it -n demo2 client2-d95b6c978-zrcxf -- curl server.demo
Server address: 172.16.9.21:80
Server name: server-6d9cc85c58-fkttn
Date: 09/May/2022:15:11:19 +0000
URI: /
Request ID: 8d77fbe42da9d94573331a9245c6e196
$ kubectl --kubeconfig=cl2.yaml exec -it -n demo2 client3-5f564bd4cc-6t57l -- curl server.demo
curl: (6) Could not resolve host: server.demo
command terminated with exit code 6
まとめ
Antrea Multi-clusterを利用することでクラスター間のSerivceリソースを同期することができました。現在データプレーンには関与していませんが、データプレーンのサポートも検討されているようです。