kubernetes上使用vcluster虛擬集群


官方主頁: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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM