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

posted @ 2022-04-11 21:55  longtds  阅读(752)  评论(0编辑  收藏  举报