Cluster API: Quá khứ, hiện tại và tương lai

cloudFun

Cluster API là một dự án chứa các API khai báo mang kiểu cấu trúc Kubernetes để tạo cluster. Nó sử dụng CRD để mở rộng API hiển thị bởi Kubernetes API Server, cho phép users tạo resources mới như Clusters (đại diện cho Kubernetes cluster) và Machines (đại diện cho các machines tạo ra Nodes để tạo cluster). Một controller (bộ điều khiển) cho mỗi resource chịu trách nhiệm phản ứng với các thay đổi của resources để phát triển cluster. API được thiết kế theo cách mà các infrastructure providers khác nhau có thể tích hợp để cung cấp logic cụ thể cho environment của họ.
EECAPmFXYAAJleU.jpg

Dự án Cluster API vẫn đang trong giai đoạn đầu, nhưng những gì đã đạt được chứng minh sức mạnh to lớn mà nó mang lại. Mục đích của bài viết này là để tóm lược các tiềm năng của dự án cho đến nay và lên kế hoạch cho các phiên bản tiếp theo.

Quá khứ, hiện tại và tương lai
Tại thời điểm viết bài, bản phát hành gần đây nhất của Cluster API là phiên bản v1alpha2. Việc chuyển đổi API và cách các providers có thể tích hợp với nó sẽ được thảo luận trong bài viết này.

Quá khứ: v1alpha1
Việc triển khai v1alpha1 ban đầu của Cluster API yêu cầu providers có Cluster API controller code trong dự án và triển khai các actuators (giao diện) để xử lý logic cụ thể cho environment (ví dụ như gọi đến cloud provider APIs ). Code này chạy dưới dạng binary của một nhà quản lý cụ thể của một provider, quản lý controller cho từng resources cần thiết để quản lý cluster.

Hiện tại: v1alpha2
Một trong những điểm mấu chốt của phương pháp v1alpha1 chi phối Cluster API là nó yêu cầu mỗi provider thực thi một số lượng bootstrap boilerplate code nhất định và kubeadm thường được sử dụng. Để khắc phục vấn đề này, v1alpha2 giới thiệu các bootstrap providers chịu trách nhiệm tạo data cần thiết để biến Machine thành Kubernetes Node. Kubeadm bootstrap provider là bootstrap provider implementation có khả năng xử lý tác vụ này cho tất cả environments sử dụng kubeadm. Cách xử lý mặc định là tạo cloud-config script cho mỗi Machine để khởi động Node.

Một thay đổi khác được giới thiệu bởi v1alpha2 là providers không cần thiết phải có Cluster API controller code trong dự án nữa. Thay vào đó, Cluster API cung cấp controllers độc lập chịu trách nhiệm về core types. Để biết chi tiết thêm về các động lực đằng sau những thay đổi này, hãy xem đề xuất này.

Đối với phiên bản này, hiện có 3 managers (thay vì một) cần được triển khai:

Cluster API manager: quản lý core v1alpha2 resources
Bootstrap provider manager: quản lý resources tạo data để biến Machine thành Kubernetes Node.
Infrastructure provider manager: quản lý các resources cung cấp hạ tầng cần thiết để chạy cluster.
Ví dụ: nếu muốn tạo một cluster trên GCP được định cấu hình bằng kubeadm, thì cần triển khai Cluster API manager (để tương thích core resources, ví dụ như Cluster và Machine resources), kubeadm bootstrap provider (để tương thích KubeadmConfig resources chẳng hạn) và GCP infrastructure provider (để kiểm tra các environment resources cụ thể, ví dụ như GCPClusters và GCPMachines).

Để xem các resources này nên được áp dụng như thế nào, việc triển khai cluster sẽ được chạy thử bằng cách sử dụng triển khai Kubernetes infrastructure provider - đó là provider nơi infrastructure được cung cấp bởi chính Kubernetes. Kubernetes Nodes chạy dưới dạng Kubernetes Pods bằng kind images.

Đầu tiên cần tạo cluster cơ sở để cung cấp hạ tầng cho Cluster API cluster, sẽ dùng đến GKE. Giả sử rằng các lệnh sau đã cài đặt gcloud với GCP project và tài khoản thanh toán được thiết lập.

CẢNH BÁO: các lệnh gcloud sẽ mất phí - nên hãy cân nhắc sử dụng GCP Free Tier.

Calico sẽ được dùng làm giải pháp CNI cho Cluster API cluster. Điều này đòi hỏi một số cấu hình cụ thể khi cung cấp GKE cluster định tuyến IPv4 encapsulated packets. Để không bị phân tâm bởi các mô tả cách xử lý Cluster API thì chúng sẽ được chạy tại đây. Tham khảo kho lưu trữ của Kubernetes infrastructure provider để biết chi tiết.
Mã:
gcloud container clusters create management-cluster --cluster-version=1.14 --image-type=UBUNTU
CLUSTER_CIDR=$(gcloud container clusters describe management-cluster --format="value(clusterIpv4Cidr)")
gcloud compute firewall-rules create allow-management-cluster-pods-ipip --source-ranges=$CLUSTER_CIDR --allow=ipip
kubectl apply -f <(cat <<EOF
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: forward-ipencap
  namespace: kube-system
  labels:
    app: forward-ipencap
spec:
  selector:
    matchLabels:
      name: forward-ipencap
  template:
    metadata:
      labels:
        name: forward-ipencap
    spec:
      hostNetwork: true
      initContainers:
      - name: forward-ipencap
        command:
        - sh
        - -c
        - |
          apk add iptables
          iptables -C FORWARD -p ipencap -j ACCEPT || iptables -A FORWARD -p ipencap -j ACCEPT
        image: alpine:3.11
        securityContext:
          capabilities:
            add: ["NET_ADMIN"]
      containers:
      - name: sleep-forever
        image: alpine:3.11
        command: ["tail"]
        args: ["-f", "/dev/null"]
EOF
)
Với GKE cluster được cung cấp, Bây giờ có thể triển khai các managers cần thiết.
Mã:
 Install cluster api manager
kubectl apply -f https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.2.8/cluster-api-components.yaml

# Install kubeadm bootstrap provider
kubectl apply -f https://github.com/kubernetes-sigs/cluster-api-bootstrap-provider-kubeadm/releases/download/v0.1.5/bootstrap-components.yaml

# Install kubernetes infrastructure provider
kubectl apply -f https://github.com/dippynark/cluster-api-provider-kubernetes/releases/download/v0.2.1/provider-components.yaml

# Allow cluster api controller to interact with kubernetes infrastructure resources
# If the kubernetes provider were SIG-sponsored this would not be necesarry ;)
# https://cluster-api.sigs.k8s.io/providers/v1alpha1-to-v1alpha2.html#the-new-api-groups
kubectl apply -f https://github.com/dippynark/cluster-api-provider-kubernetes/releases/download/v0.2.1/capi-kubernetes-rbac.yaml
Bây giờ có thể triển khai cluster
Mã:
kubectl apply -f <(cat <<EOF
apiVersion: infrastructure.lukeaddison.co.uk/v1alpha2
kind: KubernetesCluster
metadata:
  name: example
spec:
  controlPlaneServiceType: LoadBalancer
---
apiVersion: cluster.x-k8s.io/v1alpha2
kind: Cluster
metadata:
  name: example
spec:
  clusterNetwork:
    services:
      cidrBlocks: ["172.16.0.0/12"]
    pods:
      cidrBlocks: ["192.168.0.0/16"]
    serviceDomain: "cluster.local"
  infrastructureRef:
    apiVersion: infrastructure.lukeaddison.co.uk/v1alpha2
    kind: KubernetesCluster
    name: example
EOF
)
Xác định environment KubernetesCluster resource cụ thể sẽ cung cấp các thành phần hạ tầng cần thiết để chạy Kubernetes cluster. Ví dụ: một GCPCluster có thể cung cấp VPC, firewall rules và load balancer để tiếp cận (các) API Server. KubernetesCluster ở đây chỉ cung cấp Kubernetes Service thuộc loại LoadBalancer cho API Server. Truy vấn KubernetesCluster để xem status của nó.
Mã:
$ kubectl get kubernetescluster
NAME      PHASE         HOST             PORT   AGE
example   Provisioned   35.205.255.206   443    51s
Tham chiếu provider specific cluster resource từ core Cluster resource cung cấp chi tiết networking cho cluster. KubernetesCluster sẽ được sửa đổi để sở hữu bởi Cluster resource.

Bây giờ Machines đã sẵn sàng để triển khai. Tạo controller Machine tham chiếu infrastructure provider specific KubernetesMachine resource cùng với bootstrap provider specific KubeadmConfig resource.
Mã:
kubectl apply -f <(cat <<EOF
apiVersion: bootstrap.cluster.x-k8s.io/v1alpha2
kind: KubeadmConfig
metadata:
  name: controller
spec:
  initConfiguration:
    nodeRegistration:
      kubeletExtraArgs:
        eviction-hard: nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%
        cgroups-per-qos: "false"
        enforce-node-allocatable: ""
  clusterConfiguration:
    controllerManager:
      extraArgs:
        enable-hostpath-provisioner: "true"
---
apiVersion: infrastructure.lukeaddison.co.uk/v1alpha2
kind: KubernetesMachine
metadata:
  name: controller
---
apiVersion: cluster.x-k8s.io/v1alpha2
kind: Machine
metadata:
  name: controller
  labels:
    cluster.x-k8s.io/cluster-name: example
    cluster.x-k8s.io/control-plane: "true"
spec:
  version: "v1.17.0"
  bootstrap:
    configRef:
      apiVersion: bootstrap.cluster.x-k8s.io/v1alpha2
      kind: KubeadmConfig
      name: controller
  infrastructureRef:
    apiVersion: infrastructure.lukeaddison.co.uk/v1alpha2
    kind: KubernetesMachine
    name: controller
EOF
)
Kubeadm bootstrap provider biến KubeadmConfig resource thành cloud-config script được Kubernetes infrastructure provider sử dụng để khởi động Kubernetes Pod tạo control plane cho cluster mới.

Kubernetes infrastructure provider dựa vào systemd chạy như một phần của kind image để thực hiện; bash script được tạo từ cloud-config script để tạo và chạy các files và commands được chỉ định. Script gắn vào Pod bằng Kubernetes Secret, sau đó được kích hoạt bằng systemd path unit khi có sẵn containerd socket. Có thể thực thi vào controller Pod và chạy journalctl -u cloud-init để xem output của script này. cat /opt/cloud-init/bootstrap.sh sẽ hiển thị toàn bộ script.

Khi kubelet đang chạy, nó sẽ tự ghi nhận với cluster bằng cách tạo controller Node object trong etcd (cũng chạy trên controller Pod).

Bây giờ worker Machines đã có thể triển khai. Nó khá giống với controller Machine provisioning trừ việc sử dụng MachineDeployment, KubeadmConfigTemplate và KubernetesMachineTemplate để yêu cầu nhiều bản sao của Node worker.
Mã:
kubectl apply -f <(cat <<EOF
apiVersion: infrastructure.lukeaddison.co.uk/v1alpha2
kind: KubernetesMachineTemplate
metadata:
  name: worker
spec:
  template:
    spec: {}
---
apiVersion: bootstrap.cluster.x-k8s.io/v1alpha2
kind: KubeadmConfigTemplate
metadata:
  name: worker
spec:
  template:
    spec:
      joinConfiguration:
        nodeRegistration:
          kubeletExtraArgs:
            eviction-hard: nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%
            cgroups-per-qos: "false"
            enforce-node-allocatable: ""
---
apiVersion: cluster.x-k8s.io/v1alpha2
kind: MachineDeployment
metadata:
  name: worker
  labels:
    cluster.x-k8s.io/cluster-name: example
    nodepool: default
spec:
  replicas: 3
  selector:
    matchLabels:
      cluster.x-k8s.io/cluster-name: example
      nodepool: default
  template:
    metadata:
      labels:
        cluster.x-k8s.io/cluster-name: example
        nodepool: default
    spec:
      version: "v1.17.0"
      bootstrap:
        configRef:
          apiVersion: bootstrap.cluster.x-k8s.io/v1alpha2
          kind: KubeadmConfigTemplate
          name: worker
      infrastructureRef:
        apiVersion: infrastructure.lukeaddison.co.uk/v1alpha2
        kind: KubernetesMachineTemplate
        name: worker
EOF
)
MachineDeployments hoạt động tương tự như Kubernetes Deployments ở chỗ chúng quản lý MachineSets, từ đó quản lý số lượng bản sao mong muốn của Machines.

Bây giờ có thể truy vấn Machines đã cung cấp để xem status.
Mã:
$ kubectl get machines
NAME                      PROVIDERID                                          PHASE
controller                kubernetes://871cde5a-3159-11ea-a1c6-42010a840084   provisioning
worker-6c498c48db-4grxq                                                       pending
worker-6c498c48db-66zk7                                                       pending
worker-6c498c48db-k5kkp                                                       pending
Cũng có thể thấy KubernetesMachines tương ứng.
Mã:
$ kubectl get kubernetesmachines
NAME           PROVIDER-ID                                         PHASE          AGE
controller     kubernetes://871cde5a-3159-11ea-a1c6-42010a840084   Provisioning   53s
worker-cs95w                                                       Pending        35s
worker-kpbhm                                                       Pending        35s
worker-pxsph                                                       Pending        35s
Tất cả KubernetesMachines sẽ sớm ở trạng thái Running.
Mã:
$ kubectl get kubernetesmachines
NAME           PROVIDER-ID                                         PHASE     AGE
controller     kubernetes://871cde5a-3159-11ea-a1c6-42010a840084   Running   2m
worker-cs95w   kubernetes://bcd10f28-3159-11ea-a1c6-42010a840084   Running   1m
worker-kpbhm   kubernetes://bcd4ef33-3159-11ea-a1c6-42010a840084   Running   1m
worker-pxsph   kubernetes://bccd1af4-3159-11ea-a1c6-42010a840084   Running   1m
Có thể thấy các Pod tương ứng với KubernetesMachines.
$ kubectl get pods NAME READY STATUS RESTARTS AGE controller 1/1 Running 0 2m11s worker-cs95w 1/1 Running 0 111s worker-kpbhm 1/1 Running 0 111s worker-pxsph 1/1 Running 0 111s

Cluster API manager tạo kubeconfig và lưu trữ dưới dạng Kubernetes Secret có tên <clusterName>-kubeconfig có thể lấy và truy cập vào cluster.
Mã:
$ kubectl get secret example-kubeconfig -o jsonpath='{.data.value}' | base64 --decode > example-kubeconfig
$ export KUBECONFIG=example-kubeconfig
$ kubectl get nodes
NAME           STATUS     ROLES    AGE     VERSION
controller     NotReady   master   3m16s   v1.17.0
worker-cs95w   NotReady   <none>   2m34s   v1.17.0
worker-kpbhm   NotReady   <none>   2m32s   v1.17.0
worker-pxsph   NotReady   <none>   2m34s   v1.17.0
Bây giờ, giải pháp Calico CNI đã có thể áp dụng. Các Nodes sẽ sớm ở trạng thái Ready.
Mã:
$ kubectl apply -f https://docs.projectcalico.org/v3.11/manifests/calico.yaml
$ kubectl get nodes
NAME           STATUS   ROLES    AGE     VERSION
controller     Ready    master   5m8s    v1.17.0
worker-cs95w   Ready    <none>   4m26s   v1.17.0
worker-kpbhm   Ready    <none>   4m24s   v1.17.0
worker-pxsph   Ready    <none>   4m26s   v1.17.0
Bây giờ có thể chạy workloads trên cluster hoàn toàn mới! kubectl run nginx --image=nginx --replicas=3
Quy trình này tương tự cho các infrastructure providers khác. Những ví dụ khác có thể tìm thấy trong Cluster API quick start.

Tương lai: v1alpha3 và xa hơn
Các khả năng của Cluster API tiềm năng đã được tìm hiểu sơ lược. Một số khía cạnh thú vị khác có trong roadmap sẽ được tìm hiểu sau.

MachineHealthCheck
Trong v1alpha2, một infrastructure specific Machine có thể tự đánh dấu là lỗi và status sẽ hiện lên Machine sở hữu, nhưng không có hoạt động nào được thực hiện bởi MachineSet. Bởi vì các resources ngoài Machineset còn có thể sở hữu Machine và do đó, logic của việc khắc phục Machine sẽ được tách rời khỏi MachineSets.
MachineHealthCheck là một resource được đề xuất để mô tả các kịch bản lỗi cho Nodes và xóa Machine tương ứng sẽ xảy ra. Nó kích hoạt thao tác xóa thích hợp (ví dụ như drain) và bất kỳ resource kiểm soát nào để đưa ra Machine thay thế.

KubeadmControlPlane
Hiện tại, việc tạo HA control plane và quản lý control plane nói chung đòi hỏi phải cấu hình cẩn thận các controller Machines độc lập với cấu hình bootstrap chính xác (cần phải đi theo đúng thứ tự). v1alpha3 hỗ trợ các control plane providers với việc triển khai kubeadm control plane ban đầu. Điều này sẽ yêu cầu một vài thay đổi từ góc độ infrastructure provider nhưng sẽ cho phép users quản lý việc khởi tạo và nhân rộng control plane mà không cần tạo thủ công các Machines tương ứng. Kubeadm control plane proposal sẽ cung cấp thêm chi tiết.
Cùng với MachineHealthChecks, có thể khắc phục control plane tự động bằng cách sử dụng Cluster API.

Cluster Autoscaler
Cluster Autoscaler là một ví dụ của project có thể tận dụng Cluster API. Việc triển khai hiện tại yêu cầu mỗi cloud provider được hỗ trợ triển khai các CloudProvider và NodeGroup interfaces cần thiết để nhân rộng các nhóm phiên bản trong environment. Với sự ra đời của Cluster API, logic tự động hóa có thể triển khai theo cách provider agnostic tương tác với Cluster API resources thay vì trực tiếp với các provider specific APIs.

Tổng kết
Bài viết đã tìm hiểu khá sâu về các khả năng hiện tại của Cluster API và những kế hoạch trong tương lai gần. Đó là khoảng thời gian rất thú vị cho project vì nó hướng tới sự hoàn thiện. Với hầu hết mọi thứ liên quan đến Kubernetes, thì cơ hội đóng góp rất rộng mở.

Nguồn: https://blog.jetstack.io/
 
Top