你好,欢迎来到潮汕IT智库!
您的位置:首页 > IT资讯> 热点新闻 热点新闻
如何在 Cilium CNI 集群上运行 vCluster 虚拟集群
2024-09-18 09:49:17 作者: (评论0条)

背景

什么是虚拟集群

虚拟集群是一种在现有 Kubernetes 集群(Host 集群)之上创建的轻量级 Kubernetes 集群。它提供了一个独立的 Kubernetes 环境,但实际上是通过共享 Host 集群的资源来实现的。这种方式允许多个虚拟集群运行在同一个物理集群中,为不同的团队或项目提供隔离的开发、测试和生产环境,而不需要为每个环境创建单独的物理集群。

为什么要使用虚拟集群

  • 多租户隔离:在一个物理集群中为不同团队或项目提供独立的 Kubernetes 环境,确保资源和安全性隔离。
  • 开发与测试便利:开发人员可以快速创建和销毁与生产环境类似的虚拟集群,用于独立开发、测试和调试。
  • 资源优化:通过共享基础设施提高资源利用率,减少硬件需求和管理开销。
  • 灵活管理:虚拟集群允许独立配置、运行不同版本的 Kubernetes,有助于版本控制和灵活调整集群策略。
  • 成本降低:减少维护多个物理集群的需求,优化资源分配,降低整体成本。

vCluster 简介

vCluster[1] 是一种轻量级的虚拟集群解决方案,允许你在 Kubernetes 集群中创建和管理虚拟的 Kubernetes 集群。它是由 Loft Labs 开发的,用于多租户环境、开发测试环境以及简化复杂的 Kubernetes 集群管理。

关于 vCluster 的更多信息,后面我会再写一篇深入介绍下。

Cilium CNI 简介

Cilium[2] 是一个基于 eBPF[3](extended Berkeley Packet Filter)技术的容器网络接口(CNI)插件,旨在为 Kubernetes 和其他容器平台提供高效、安全的网络和负载均衡功能。Cilium 的核心目标是通过使用 eBPF 实现更高性能、更灵活的网络数据处理,并简化网络安全策略的管理。在之前的文章 Kubernetes 网络学习之 Cilium 与 eBPF 和 深入探索 Cilium 的工作机制 中曾介绍过

接下来我们看下如何在 Cilium CNI 集群上运行 vCluster 虚拟集群。

环境搭建

准备 Host 集群

准备 Kubernetes 集群,使用 v1.28.13+k3s1 版本的 K3s 作为 Host 集群,禁用 flannel。

export INSTALL_K3S_VERSION=v1.28.13+k3s1
curl -sfL https://get.k3s.io | sh -s - --disable traefik --disable metrics-server --flannel-backend=none --cluster-cidr=10.42.0.0/16 --disable-network-policy --write-kubeconfig-mode 644 --write-kubeconfig ~/.kube/config

集群安装后,查看 Pod 状态。Pending 状态是因为没有 CNI 插件。

kubectl get po -A
NAMESPACE     NAME                                      READY   STATUS    RESTARTS   AGE
kube-system   coredns-6799fbcd5-h8cfh                   0/1     Pending   0          41s
kube-system   local-path-provisioner-5ccc7458d5-scfq4   0/1     Pending   0          41s

安装 Cilium CNI

安装 Cilium。

curl -L --remote-name-all https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-amd64.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
rm cilium-linux-amd64.tar.gz{,.sha256sum}

目前最新的 stable 版本未 v1.16.1

cilium version
cilium-cli:  compiled with go1.23.0 on linux/amd64
cilium image (default): v1.16.0
cilium image (stable): v1.16.1
cilium image (running): unknown. Unable to obtain cilium version. Reason: release: not found

安装 Cilium 到集群:

cilium install

等待 Cilium 安装完成。

cilium status --wait
    /¯¯\
 /¯¯\__/¯¯\    Cilium:             2 warnings
    /¯¯\
 /¯¯\__/¯¯\    Cilium:             OK
 \__/¯¯\__/    Operator:           OK
 /¯¯\__/¯¯\    Envoy DaemonSet:    OK
 \__/¯¯\__/    Hubble Relay:       disabled
    \__/       ClusterMesh:        disabled

DaemonSet              cilium             Desired: 1, Ready: 1/1, Available: 1/1
Deployment             cilium-operator    Desired: 1, Ready: 1/1, Available: 1/1
DaemonSet              cilium-envoy       Desired: 1, Ready: 1/1, Available: 1/1
Containers:            cilium             Running: 1
                       cilium-envoy       Running: 1
                       cilium-operator    Running: 1
Cluster Pods:          2/2 managed by Cilium
Helm chart version:
Image versions         cilium-operator    quay.io/cilium/operator-generic:v1.16.0@sha256:d6621c11c4e4943bf2998af7febe05be5ed6fdcf812b27ad4388f47022190316: 1
                       cilium             quay.io/cilium/cilium:v1.16.0@sha256:46ffa4ef3cf6d8885dcc4af5963b0683f7d59daa90d49ed9fb68d3b1627fe058: 1
                       cilium-envoy       quay.io/cilium/cilium-envoy:v1.29.7-39a2a56bbd5b3a591f69dbca51d3e30ef97e0e51@sha256:bd5ff8c66716080028f414ec1cb4f7dc66f40d2fb5a009fff187f4a9b90b566b: 1

待 Cilium 安装完成后,所有的 Pod 都正常运行。

kubectl get po -A
NAMESPACE     NAME                                      READY   STATUS    RESTARTS   AGE
kube-system   cilium-envoy-t2vbd                        1/1     Running   0          75s
kube-system   cilium-gfk5r                              1/1     Running   0          75s
kube-system   cilium-operator-885db8fcf-kp2dr           1/1     Running   0          75s
kube-system   coredns-6799fbcd5-4xmcd                   1/1     Running   0          94s
kube-system   local-path-provisioner-5ccc7458d5-scfq4   1/1     Running   0          94s

安装 vCluster

这里使用 vCluster CLI 来管理虚拟集群,首先安装 vCluster CLI。

curl -L -o vCluster "https://github.com/loft-sh/vCluster/releases/latest/download/vCluster-linux-amd64" && sudo install -c -m 0755 vCluster /usr/local/bin && rm -f vCluster

最新的版本为 vCluster

vCluster version
vCluster version 0.20.0

查看 Host 集群的命名空间。

kubectl get ns
NAME              STATUS   AGE
default           Active   2m8s
kube-node-lease   Active   2m8s
kube-public       Active   2m8s
kube-system       Active   2m8s

虚拟集群

创建虚拟集群

使用 vCluster create NAME 创建名为 vc-a 的虚拟集群。

vCluster create vc-a
07:02:38 info Creating namespace vCluster-vc-a
07:02:38 info Create vCluster vc-a...
07:02:38 info execute command: helm upgrade vc-a /tmp/vCluster-0.20.0.tgz-759956343 --create-namespace --kubeconfig /tmp/1343191442 --namespace vCluster-vc-a --install --repository-config='' --values /tmp/3416084562
07:02:39 done Successfully created virtual cluster vc-a in namespace vCluster-vc-a
07:02:44 info Waiting for vCluster to come up...
07:02:55 warn vCluster is waiting, because vCluster pod vc-a-0 has status: Init:2/3
07:03:15 done vCluster is up and running
07:03:15 done Switched active kube context to vCluster_vc-a_vCluster-vc-a_default
- Use `vCluster disconnect` to return to your previous kube context
- Use `kubectl get namespaces` to access the vCluster

vCluster 会在 Host 集群上为虚拟集群创建一个独立的命名空间,比如这里的 vCluster-vc-a 就是虚拟集群 vc-a 在 Host 集群上的命名空间。

kubectl get ns
NAME              STATUS   AGE
default           Active   7m51s
kube-node-lease   Active   7m51s
kube-public       Active   7m51s
kube-system       Active   7m51s
vCluster-vc-a     Active   2m8s

在该命名空间下,有 vCluster 的控制面和 coredns。默认情况下,vCluster 的组件都是 StatefulSet 单实例运行。这种单实例架构适合开发环境或者 CI/CD 环境,但生产环境建议使用 高可用方案[4] 部署。

kubectl get po -n vCluster-vc-a
NAME                                            READY   STATUS    RESTARTS   AGE
coredns-5c7466bb88-zgqqk-x-kube-system-x-vc-a   1/1     Running   0          2m19s
vc-a-0                                          1/1     Running   0          2m49s

这里 vc-a-0 就是虚拟集群 vc-a 的控制面实例,在这个实例中包含了:

  • Kubernetes API server:Kubernetes API 服务器,它是虚拟集群内所有 API 请求的管理接口。
  • controller manager:控制器管理器,用于维护 pod 等 Kubernetes 资源的状态,确保它们匹配所需的配置。
  • data store:数据存储,是 API 存储所有资源的数据存储。默认使用内置的 SQLite,通过 PVC 做持久化存储。
  • syncer:同步器,用于同步虚拟集群和主机集群之间的资源,并完成主机基础设施上的工作负载管理。
  • scheduler:调度程序,它是调度工作负载的可选组件。默认情况下,vCluster 重用主机集群调度程序以节省计算资源。如果需要添加节点标签或污点来控制调度、排出节点或利用自定义调度程序,可以启用虚拟调度程序。

使用同样的方式,我们再创建一个虚拟集群 vc-b

vCluster create vc-b

查看已有的虚拟集群。

vCluster list

    NAME |   NAMESPACE   | STATUS  | VERSION | CONNECTED |  AGE
  -------+---------------+---------+---------+-----------+---------
    vc-a | vCluster-vc-a | Running | 0.20.0  |           | 41m34s
    vc-b | vCluster-vc-b | Running | 0.20.0  |           | 16m36s

虚拟集群的 KubeConfig

虚拟集群的 KubeConfig 保存在对应的 Host 集群的命名空间中,比如虚拟集群 vc-a 的 kubeconfig 保存在 Host 集群的命名空间 vCluster-vc-a 下的 Secret vc-vc-a 中。

kubectl get secret -n vCluster-vc-a
NAME                         TYPE                 DATA   AGE
sh.helm.release.v1.vc-a.v1   helm.sh/release.v1   1      46m
vc-a-certs                   Opaque               25     46m
vc-config-vc-a               Opaque               1      46m
vc-vc-a                      Opaque               4      45m

通过下面的命令可以查看 kubeconfig 的内容。

kubectl get secret -n vCluster-vc-a vc-vc-a -o jsonpath='{.data.config}' | base64 -d

连接到虚拟集群

要连接到虚拟集群不需要直接使用 kubeconfig,vCluster CLI 提供了命令可以快捷地连接到虚拟集群。

07:51:42 done vCluster is up and running
07:51:42 done Switched active kube context to vCluster_vc-a_vCluster-vc-a_default
- Use `vCluster disconnect` to return to your previous kube context
- Use `kubectl get namespaces` to access the vCluster

连接成功后,就可以操作虚拟集群了。

kubectl get po -A
NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE
kube-system   coredns-5c7466bb88-zgqqk   1/1     Running   0          48m

通过命令 vCluster disconnect 可以断开连接,切换到 Host 集群。

测试

部署实例应用

在虚拟集群 vc-a 上部署应用 deathstartiefighter 和 xwing

cat <---
apiVersion: v1
kind: Service
metadata:
  name: deathstar
  labels:
    app.kubernetes.io/name: deathstar
spec:
  type: ClusterIP
  ports:
  - port: 80
  selector:
    org: empire
    class: deathstar
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deathstar
  labels:
    app.kubernetes.io/name: deathstar
spec:
  replicas: 2
  selector:
    matchLabels:
      org: empire
      class: deathstar
  template:
    metadata:
      labels:
        org: empire
        class: deathstar
        app.kubernetes.io/name: deathstar
    spec:
      containers:
      - name: deathstar
        image: docker.io/cilium/starwars
---
apiVersion: v1
kind: Pod
metadata:
  name: tiefighter
  labels:
    org: empire
    class: tiefighter
    app.kubernetes.io/name: tiefighter
spec:
  containers:
  - name: spaceship
    image: docker.io/tgraf/netperf
---
apiVersion: v1
kind: Pod
metadata:
  name: xwing
  labels:
    app.kubernetes.io/name: xwing
    org: alliance
    class: xwing
spec:
  containers:
  - name: spaceship
    image: docker.io/tgraf/netperf
EOF

待应用启动后测试服务调用。

kubectl exec tiefighter -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing
kubectl exec xwing -- curl -s -XPOST deathstar.default.svc.cluster.local/v1/request-landing

如果显示下面的结果,访问正常,说明容器网络没有问题。

Ship landed
Ship landed

总结

vCluster 在使用 Cilium CNI 的 Host 集群上容器网络是没有问题的,可以说 vCluster 使用的还是 Host 集群的容器网络,不受 CNI 实现的影响。

但如果要在虚拟集群上使用 Cilium 的网络策略,则会受到限制。

这是因为 Syncer 是 vCluster 架构中的一个关键组件,负责在虚拟集群和 Host 集群之间同步 Kubernetes 资源。它使得 vCluster 能够在宿主集群上运行,同时保持与虚拟集群的 Kubernetes API Server 一致。

简单说 Syncer 在 Host 集群和虚拟集群间完成资源的“转译”,实现资源的同步,但仅限于 Kubernetes 的原生资源(如 Pods、Services、ConfigMaps 等)。

在 vCluster v0.14 - 0.19 中,可以通过扩展 vcluster-generic-crd-sync-plugin[5] 完成特定 CRD 的同步,但这个仓库已经一年多未更新。


相关文章
如何在 Cilium CNI 集群上运行...
Java8 Steam流太难用了?那你可...
太赞了!十年开发大牛直接用3000字就把...
英特尔的代工往事...