Kubernetes Multitenancy với vCluster

5 min read

vCluster

Multitenancy là khó khăn và đôi khi gây nản lòng, đặc biệt đối với các platform administrators. Các mô hình multitenancy phổ biến nhất là:

  • Cluster-based isolation
  • Namespace based isolation

Cluster-based isolation: Mỗi tenant sẽ có một cluster riêng của họ. Điều này có lợi về mặt cô lập tốt hơn và mỗi cluster ít phức tạp hơn từ quan điểm cấu hình. Tuy nhiên, hãy tưởng tượng có hàng ngàn tenants, tạo ra một cluster cho mỗi tenant có thể rất khó khăn hoặc thậm chí không thể quản lý được. Ngoài ra, chi phí đặc biệt là trong môi trường dựa trên Cloud có thể cao.

Namespace based isolation Tenants bị hạn chế trong một hoặc nhiều namespace riêng biệt trong một cluster Kubernetes chia sẻ. Bằng cách sử dụng cách tiếp cận này, chúng ta không cần phải có các cluster cho mỗi tenant do đó, ít tài nguyên bị lãng phí và tiết kiệm chi phí nhưng, môi trường cơ bản có thể trở nên phức tạp.

vCluster là gì?

Sau một số tìm hiểu về cảnh quan của cloud native, vCluster đã được đề cập. vCluster cung cấp khả năng tạo các cụm ảo chạy bên trong một cụm Kubernetes chia sẻ, nhưng chúng xuất hiện cho người dùng cuối như một cụm độc lập, đứng riêng biệt.

Lab Setup

+----------------------+------------+-------------------------------------+
|    Cluster Name      |  Version   |              Comments               |
+----------------------+------------+-------------------------------------+
|   civo-cluster01     | v1.28.7+k3s1|  Civo 3 Node - Medium Standard     |
|   vcluster-dev       | v1.29.0+k3s1|  Defined in the `dev` namespace    |
|   vcluster-staging   | v1.29.0+k3s1|  Defined in the `staging` namespace|
+----------------------+------------+-------------------------------------+

Prerequisites

  1. Helm version ≥ v3.10.0
  2. kubectl available: Use the guide found here

Tải xuống và export Kubeconfig Chuẩn — Civo Portal

Như đã đề cập ở trên, chúng ta đã cấu hình một cụm Kubernetes ba node bằng Civo. Thêm thông tin về cách tạo một cụm và lấy kubeconfig có thể được tìm thấy ở đây.

Export KUBECONFIG

$ export KUBECONFIG=~/demo/vcluster/civo-cluster01.yaml

Chuẩn bị tệp value.yaml

Vì chúng ta muốn truy cập vào các cụm ảo thông qua địa chỉ IP của Loadbalancer, chúng ta sẽ tạo một tệp custom-values-<env>.yaml cùng với một dịch vụ có kiểu LoadBalancer. Sau đó, chúng ta sẽ truyền nó như một đối số trong quá trình cài đặt Helm.

LoadBalancer Service

cat vcluster-loadbalancer.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: vcluster-loadbalancer
  namespace: dev
spec:
  selector:
    app: vcluster
    release: vcluster-dev
  ports:
    - name: https
      port: 443
      targetPort: 8443
      protocol: TCP
  type: LoadBalancer
$ kubectl get svc -n dev | grep -i LoadBalancer
vcluster-loadbalancer                                           LoadBalancer   10.43.141.220   x.x.x.x   443:31043/TCP            38m

vcluster-dev 

$ cat custom-values-dev.yaml
# Checkout the HA documentation: https://www.vcluster.com/docs/v0.19/deploying-vclusters/high-availability

# Scale up syncer replicas
syncer:
  replicas: 1
  extraArgs:
    - --tls-san=<LoadBalancer IP>

# Scale up etcd
etcd:
  replicas: 1

# Scale up DNS server
coredns:
  replicas: 1

# Virtual Cluster (k3s) configuration
vcluster:
  # Image to use for the virtual cluster
  image: rancher/k3s:v1.29.0-k3s1

# Specify an initial cluster configuration
init:
  manifests: |-
    ---
    apiVersion: v1
    kind: Namespace
    metadata:
      name: nginx-app
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-dev
      namespace: nginx-app
    spec:
      selector:
        matchLabels:
          app: nginx
      replicas: 1
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:latest
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-dev
      namespace: nginx-app
    spec:
      selector:
        app: nginx
      ports:
        - protocol: TCP
          port: 80
          targetPort: 80
      type: ClusterIP

Trong YAML trên, điều quan trọng nhất là:

Đầu tiên, chúng ta chỉ định phiên bản k3s và xác định extraArgs với địa chỉ IP của LoadBalancer đã tạo ở trên. Điều thú vị là chúng ta có khả năng triển khai bất kỳ tài nguyên Kubernetes cần thiết nào trong quá trình cài đặt Helm chart (init.manifests). Trong trường hợp này, chúng ta triển khai một ứng dụng Nginx đơn giản trong namespace nginx-app.

Nếu yêu cầu Có Sẵn Cao (HA), chúng ta có thể cập nhật số bản sao của các phần syncer, etcd, coredns.

Lưu ý: Tùy thuộc vào trường hợp sử dụng, chúng ta có thể xác định các tài nguyên Kubernetes dưới đây phần init như manifests hoặc như Helm Charts.

Cài đặt vCluster Helm

Với tệp giá trị tùy chỉnh cho quá trình cài đặt sẵn sàng, chúng ta có thể tiến hành triển khai các cụm ảo.

$ kubectl create namespace dev

$ helm upgrade --install vcluster-dev vcluster --namespace dev --values ~/demo/vcluster/multi-tenant/values/custom-values-dev.yaml --repo https://charts.loft.sh  --repository-config=''

Release "vcluster-dev" does not exist. Installing it now.
NAME: vcluster-dev
LAST DEPLOYED: Mon Apr 29 10:24:30 2024
NAMESPACE: dev
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Thank you for installing vcluster.

Your vcluster is named vcluster-dev in namespace dev.

To connect to the vcluster, use vcluster CLI (https://www.vcluster.com/docs/getting-started/setup):
  $ vcluster connect vcluster-dev -n dev
  $ vcluster connect vcluster-dev -n dev -- kubectl get ns


For more information, please take a look at the vcluster docs at https://www.vcluster.com/docs

Kiểm tra lại

$ helm list -n dev
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
vcluster-dev    dev             1               2024-04-29 10:24:30.052973137 +0000 UTC deployed        vcluster-0.19.5 0.19.5   

$ kubectl get pods,svc,secret -n dev
NAME                                                        READY   STATUS    RESTARTS   AGE
pod/nginx-dev-7c79c4bf97-6ln7q-x-nginx-app-x-vcluster-dev   1/1     Running   0          3m2s
pod/vcluster-dev-0                                          1/1     Running   0          3m26s
pod/coredns-68bdd584b4-qrv2z-x-kube-system-x-vcluster-dev   1/1     Running   0          3m2s

NAME                                                                    TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)                  AGE
service/vcluster-loadbalancer                                           LoadBalancer   10.43.141.220   x.x.x.x.       443:31043/TCP            18m
service/vcluster-dev-headless                                           ClusterIP      None            <none>         443/TCP                  3m26s
service/vcluster-dev                                                    ClusterIP      10.43.169.7     <none>         443/TCP,10250/TCP        3m26s
service/vcluster-dev-node-k3s-demo01-49d0-a793bf-node-pool-1f89-nwlte   ClusterIP      10.43.240.210   <none>         10250/TCP                3m2s
service/vcluster-dev-node-k3s-demo01-49d0-a793bf-node-pool-1f89-wib2n   ClusterIP      10.43.203.185   <none>         10250/TCP                3m2s
service/kube-dns-x-kube-system-x-vcluster-dev                           ClusterIP      10.43.103.34    <none>         53/UDP,53/TCP,9153/TCP   3m2s
service/nginx-dev-x-nginx-app-x-vcluster-dev                            ClusterIP      10.43.169.94    <none>         80/TCP                   3m2s

NAME                                        TYPE                 DATA   AGE
secret/vc-k3s-vcluster-dev                  Opaque               1      17m
secret/sh.helm.release.v1.vcluster-dev.v1   helm.sh/release.v1   1      3m26s
secret/vc-vcluster-dev                      Opaque               4      3m2s

Retrieve vCluster Kubeconfig

Sau khi cài đặt cụm ảo, chúng ta có thể truy xuất kubeconfig bằng cách giải mã cấu hình bí mật với tên vc-cluster-dev.

$ kubectl get secret vc-vcluster-dev -n dev --template={{.data.config}} | base64 -d > ~/demo/vcluster/multi-tenant/kubeconfig/vcluster-dev.yaml

Tương tác với vCluster

Miễn là chúng ta có kubeconfig có sẵn, chúng ta có thể xuất biến KUBECONFIG và bắt đầu tương tác với nó. Theo dõi các lệnh dưới đây để xác nhận và tương tác tiếp theo.

$ export KUBECONFIG=~/demo/vcluster/multi-tenant/kubeconfig/vcluster-dev.yaml

$ kubectl get nodes,ns
NAME                                               STATUS   ROLES    AGE   VERSION
node/k3s-demo01-49d0-a793bf-node-pool-1f89-nwlte   Ready    <none>   11m   v1.29.0+k3s1
node/k3s-demo01-49d0-a793bf-node-pool-1f89-wib2n   Ready    <none>   11m   v1.29.0+k3s1

NAME                        STATUS   AGE
namespace/kube-system       Active   21m
namespace/kube-public       Active   21m
namespace/kube-node-lease   Active   21m
namespace/default           Active   21m
namespace/nginx-app         Active   21m

$ kubectl get pods,svc -n nginx-app
NAME                             READY   STATUS    RESTARTS   AGE
pod/nginx-dev-7c79c4bf97-6ln7q   1/1     Running   0          8m22s

NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/nginx-dev   ClusterIP   10.43.169.94   <none>        80/TCP    7m32s

Trong bài viết này, chúng tachỉ sử dụng duy nhất Helm và kubectl, điều này khiến việc tích hợp với một bộ điều khiển add-on Kubernetes và một Pipeline để tự động hóa trở nên mượt mà.

Avatar photo

Clean Code: Nguyên tắc viết hàm trong lập trình…

Trong quá trình phát triển phần mềm, việc viết mã nguồn dễ đọc, dễ hiểu là yếu tố then chốt để đảm bảo code...
Avatar photo Dat Tran Thanh
3 min read

Leave a Reply

Your email address will not be published. Required fields are marked *