官方主頁:https://www.vcluster.com
開源地址:https://github.com/loft-sh/vcluster
簡述虛擬集群
虛擬集群是完整的Kubernetes集群,運行在其他Kubernetes集群之上。與完全獨立的“真實”集群相比,虛擬集群沒有自己的節點池。但是它們可以在底層集群內調度工作負載,同時具有自己單獨的控制平面。
虛擬集群本身僅由核心Kubernetes組件組成:API服務器、控制器管理器和存儲后端(如 etcd、sqlite、mysql等)。
虛擬集群支持多種Kubernetes發行版,如k0s、k3s和k8s。除了控制平面之外,還有一個 Kubernetes虛擬機監控程序,它取代了Kubernetes調度程序,並模擬了虛擬集群中完整的Kubernetes設置。此組件在虛擬集群和主機集群之間同步對集群功能至關重要的核心資源:
- Pod:在虛擬集群中啟動的所有容器都將被重寫,然后在主機集群中虛擬集群的命名空間中啟動。ServiceAccount、ENV、DNS和其他配置將交換為指向虛擬集群而不是主機集群。在容器中,容器似乎是在虛擬集群中啟動的,而不是在主機集群中啟動的。
- Service:所有servcie和endpoint都在主機集群的虛擬集群的命名空間中重寫和創建。虛擬集群和主機集群共享相同的服務集群IP。這也意味着可以從虛擬集群內訪問主機集群中的服務,而不會降低任何性能。
- PVC:如果在虛擬集群中創建了PVC,則它們將同步在主機集群的虛擬集群所在的命名空間中創建。如果它們綁定了主機集群中的PV,則相應的PV信息將同步回虛擬集群。
- ConfigMap和Secret:虛擬集群中掛載到Pod的ConfigMap或Secret將同步到主機集群,所有其他ConfigMap或Secret將保留在虛擬集群中。
- 其他資源:Deployment、Statefulset、CRD、ServiceAccount等不會同步到主機集群,而是純粹存在於虛擬集群中。
除了同步虛擬和主機集群資源之外,虛擬機監控程序還將某些Kubernetes API請求代理到主機集群,例如pod端口轉發或容器命令執行。它實質上充當虛擬集群的反向代理。
虛擬集群的優勢
虛擬集群解決了命名空間存在的許多問題,例如:
- 集群范圍的資源:某些資源全局存在於集群中,無法使用命名空間隔離它們。例如,無法在單個集群中以不同的版本安裝istio或任何其他組件。虛擬集群具備獨立的資源管理並且被隔離在獨立的命名空間中。
- 共享Kubernetes控制平面:API服務器、etcd、調度程序和控制器管理器在單個 Kubernetes集群中共享。基於命名空間的請求或存儲速率限制非常困難,錯誤的配置可能會使整個集群癱瘓。虛擬集群提供了完整的控制平面。
啟用虛擬集群
# 下載vcluster工具
[root@vm ~]# curl -s -L "https://github.com/loft-sh/vcluster/releases/latest" | sed -nE 's!.*"([^"]*vcluster-linux-amd64)".*!https://github.com\1!p' | xargs -n 1 curl -L -o vcluster && chmod +x vcluster;
[root@vm ~]# sudo mv vcluster /usr/local/bin;
[root@vm ~]# vcluster -v
vcluster version 0.7.1
# 為了能通過主機集群的NodePort獨立訪問虛擬集群API,先創建NodePort服務
[root@vm ~]# cat vcluster-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: vcluster-nodeport
spec:
selector:
app: vcluster
ports:
- name: https
port: 443
targetPort: 8443
protocol: TCP
type: NodePort
# 主機集群上創建部署虛擬集群的命名空間和NodePort服務
[root@vm ~]# kubectl create ns vcluster-1
namespace/vcluster-1 created
[root@vm ~]# kubectl apply -f vcluster-nodeport.yaml -n vcluster-1
service/vcluster-nodeport created
[root@vm ~]# kubectl get svc vcluster-nodeport -n vcluster-1
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
vcluster-nodeport NodePort 10.43.112.147 <none> 443:32121/TCP 47s
# 創建vcluster配置文件,添加虛擬集群訪問ip,即主機集群節點地址
[root@vm ~]# cat value.yaml
syncer:
extraArgs:
- --tls-san=192.168.x.11,192.168.x.12,192.168.x.13
# 創建虛擬集群,使用k0s發行版
[root@vm ~]# vcluster create vcluster-1 -n vcluster-1 --distro k0s -f value.yaml
[info] officially unsupported host server version 1.20, will fallback to virtual cluster version v1.22
[info] execute command: helm upgrade vcluster-1 vcluster-k0s --repo https://charts.loft.sh --version 0.7.1 --kubeconfig C:\Users\wangw\DOCUME~1\MOBAXT~1\slash\tmp\1920354934 --namespace vcluster-1 --install --repository-config='' --values C:\Users\wangw\DOCUME~1\MOBAXT~1\slash\tmp\2268190059 --values value.yaml
[done] √ Successfully created virtual cluster vcluster-1 in namespace vcluster-1.
- Use 'vcluster connect vcluster-1 --namespace vcluster-1' to access the virtual cluster
- Use `vcluster connect vcluster-1 --namespace vcluster-1 -- kubectl get ns` to run a command directly within the vcluster
# 從主機集群中查看vcluster-1命名空間資源
[root@vm ~]# kubectl get all -n vcluster-1
NAME READY STATUS RESTARTS AGE
pod/coredns-86d5cb86f5-k9t4c-x-kube-system-x-vcluster-1 1/1 Running 0 32s
pod/vcluster-1-0 2/2 Running 0 95s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
AGE
service/kube-dns-x-kube-system-x-vcluster-1 ClusterIP 10.43.94.24 <none> 53/UDP,53/TCP,9153/TCP
33s
service/vcluster-1 ClusterIP 10.43.227.133 <none> 443/TCP
97s
service/vcluster-1-headless ClusterIP None <none> 443/TCP
97s
service/vcluster-1-node-vm190118 ClusterIP 10.43.94.216 <none> 10250/TCP
33s
service/vcluster-nodeport NodePort 10.43.112.147 <none> 443:32121/TCP
8m37s # 虛擬集群API對外訪問端口32121
NAME READY AGE
statefulset.apps/vcluster-1 1/1 97s # 虛擬集群控制平面
使用虛擬集群
# 獲取虛擬集群kubeconfig
[root@vm ~]# vcluster connect vcluster-1 -n vcluster-1 --server=https://192.168.x.11:32121
[info] Use `vcluster connect vcluster-1 -n vcluster-1 -- kubectl get ns` to execute a command directly within this terminal
[done] √ Virtual cluster kube config written to: ./kubeconfig.yaml. You can access the cluster via `kubectl --kubeconfig ./kubeconfig.yaml get namespaces`
[root@vm ~]# ls
vcluster-nodeport.yaml kubeconfig.yaml value.yaml
# 配置當前kubectl會話使用虛擬集群的kubeconfig
[root@vm ~]# export KUBECONFIG=./kubeconfig.yaml
[root@vm ~]# kubectl get ns
NAME STATUS AGE
default Active 7m36s
kube-node-lease Active 7m50s
kube-public Active 7m50s
kube-system Active 7m51s
# 虛擬集群下只有coredns組件
[root@vm ~]# kubectl get po -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-86d5cb86f5-k9t4c 1/1 Running 0 9m2s
# 在虛擬集群下創建應用
[root@vm ~]# kubectl run nginx --image=nginx:stable --port=80
pod/nginx created
[root@vm ~]# kubectl get po
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 36s
# 此時在主機集群下查看pod,會發現虛擬集群下創建的pod直接同步到了其主機集群命名空間下,並且pod名稱附帶了pod在虛擬集群下的命名空間和虛擬集群名稱
[root@vm ~]# kubectl get po -n vcluster-1
NAME READY STATUS RESTARTS AGE
coredns-86d5cb86f5-k9t4c-x-kube-system-x-vcluster-1 1/1 Running 0 13m
nginx-x-default-x-vcluster-1 1/1 Running 0 58s
vcluster-1-0 2/2 Running 0 15m
# 為虛擬集群的應用創建servcie
[root@vm ~]# kubectl expose pod nginx --port=80
service/nginx exposed
[root@vm ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.227.133 <none> 443/TCP 20m
nginx ClusterIP 10.43.146.179 <none> 80/TCP 6s
# 再查看主機集群下的虛擬集群所在命名空間的服務,虛擬集群中的應用服務也被同步了出來
[root@vm ~]# kubectl get svc -n vcluster-1
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns-x-kube-system-x-vcluster-1 ClusterIP 10.43.94.24 <none> 53/UDP,53/TCP,9153/TCP 22m
nginx-x-default-x-vcluster-1 ClusterIP 10.43.146.179 <none> 80/TCP 101s
vcluster-1 ClusterIP 10.43.227.133 <none> 443/TCP 23m
vcluster-1-headless ClusterIP None <none> 443/TCP 23m
vcluster-1-node-vm190118 ClusterIP 10.43.94.216 <none> 10250/TCP 22m
vcluster-nodeport NodePort 10.43.112.147 <none> 443:32121/TCP 30m
清理虛擬集群
[root@vm ~]# vcluster delete vcluster-1 -n vcluster-1
[info] Delete helm chart with helm delete vcluster-1 --namespace vcluster-1 --kubeconfig C:\Users\wangw\DOCUME~1\MOBAXT~1\slash\tmp\89266231 --repository-config=''
[done] √ Successfully deleted virtual cluster vcluster-1 in namespace vcluster-1
[done] √ Successfully deleted virtual cluster pvc data-vcluster-1-0 in namespace vcluster-1