文档

使用ASM与Karmada实现多集群应用管理

更新时间:

服务网格 ASM(Service Mesh)支持与Karmada(Kubernetes Armada)配合,使您能够在多个Kubernetes集群中部署和运行云原生应用程序,而无需更改应用程序。Karmada提供了为云原生场景下的多集群应用程序管理提供即插即用的自动化,具有集中式多云管理、高可用性、故障恢复和流量调度等关键功能。本文介绍如何使用ASM与Karmada实现多集群应用管理。

背景信息

Karmada使用Kubernetes原生API定义联邦资源模板,以便轻松与现有Kubernetes采用的工具进行集成。同时,Karmada也提供了一个独立的Propagation (placement) Policy API 来定义多集群的调度要求。

  • 支持1:N的策略映射机制。您无需每次创建联邦应用时都标明调度约束。

  • 在使用默认策略的情况下,您可以直接与Kubernetes API交互。

集群模式

Karmada支持通过PushPull两种模式来管理成员集群。PushPull模式的主要区别在于部署资源清单时,访问成员集群的方式。

Push模式

Karmada控制平面将直接访问成员集群的kube-apiserver,以获取集群状态并部署资源清单。

Pull模式

Karmada 控制平面不会直接访问成员集群,而是将其请求下放给名为karmada-agent的额外组件处理。

每个karmada-agent服务于一个集群,并承担以下职责:

  • 将集群注册到 Karmada 中(创建Cluster对象)

  • 维护集群状态并向 Karmada 报告(更新Cluster对象的状态)

  • 监听来自 Karmada 执行空间(命名空间,格式为karmada-es-<cluster name>)的资源清单,并将监听到的资源部署到其所服务的集群中。

关键组件

Karmada的控制面包括以下组件:

  • Karmada API Server。

  • Karmada Controller Manager。

  • Karmada Scheduler。

ETCD存储了Karmada API对象,API Server是所有其他组件通讯的REST端点,Karmada Controller Manager根据您通过API服务器创建的API对象执行操作。

image

前提条件

  • 在同一VPC下,已创建两个ACK集群(本示例为member1和member2)。具体操作,请参见创建ACK托管集群

    说明
    • 本示例以同一个VPC的两个集群作为示例场景。如果使用不同的VPC,则需要额外配置以使跨VPC能够在物理网络上连通。

    • 在创建集群时,建议使用企业安全组。

  • 创建ASM实例(本示例为mesh1),且已在default命名空间上配置Sidecar注入策略

  • 已部署一个Karmada主集群实例(本示例为karmada-master),并将上述两个ACK集群作为成员集群(本示例为member1和member2)添加到Karmada主集群中。具体操作,请参见Karmada Installation

  • 已添加两个集群到ASM实例(mesh1),并创建Serverless入口网关。具体操作,请参见添加集群到ASM实例并创建Serverless入口网关

步骤一:使用Karmada在多集群中部署应用

使用ASM Serverless网关实现多集群入口中相同,本文同样使用Bookinfo示例。不同于手动将review-3和review-1、review-2分别部署到两个集群中的方式,本节演示基于karmada的Propagation Policy,只需在karmada-master集群中创建传播策略,即可实现同样的效果。

  1. 使用以下内容创建bookinfo-karmada.yaml。

    展开查看YAML内容

    # Details service
    apiVersion: v1
    kind: Service
    metadata:
      name: details
      labels:
        app: details
        service: details
    spec:
      ports:
      - port: 9080
        name: http
      selector:
        app: details
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: bookinfo-details
      labels:
        account: details
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: details-v1
      labels:
        app: details
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: details
          version: v1
      template:
        metadata:
          labels:
            app: details
            version: v1
        spec:
          serviceAccountName: bookinfo-details
          containers:
          - name: details
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/examples-bookinfo-details-v1:1.19.1
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 9080
    ---
    # Ratings service
    apiVersion: v1
    kind: Service
    metadata:
      name: ratings
      labels:
        app: ratings
        service: ratings
    spec:
      ports:
      - port: 9080
        name: http
      selector:
        app: ratings
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: bookinfo-ratings
      labels:
        account: ratings
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ratings-v1
      labels:
        app: ratings
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ratings
          version: v1
      template:
        metadata:
          labels:
            app: ratings
            version: v1
        spec:
          serviceAccountName: bookinfo-ratings
          containers:
          - name: ratings
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/examples-bookinfo-ratings-v1:1.19.1
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 9080
    ---
    # Reviews service
    apiVersion: v1
    kind: Service
    metadata:
      name: reviews
      labels:
        app: reviews
        service: reviews
    spec:
      ports:
      - port: 9080
        name: http
      selector:
        app: reviews
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: bookinfo-reviews
      labels:
        account: reviews
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: reviews-v1
      labels:
        app: reviews
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: reviews
          version: v1
      template:
        metadata:
          labels:
            app: reviews
            version: v1
        spec:
          serviceAccountName: bookinfo-reviews
          containers:
          - name: reviews
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/examples-bookinfo-reviews-v1:1.19.1
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 9080
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: reviews-v2
      labels:
        app: reviews
        version: v2
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: reviews
          version: v2
      template:
        metadata:
          labels:
            app: reviews
            version: v2
        spec:
          serviceAccountName: bookinfo-reviews
          containers:
          - name: reviews
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/examples-bookinfo-reviews-v2:1.19.1
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 9080
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: reviews-v3
      labels:
        app: reviews
        version: v3
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: reviews
          version: v3
      template:
        metadata:
          labels:
            app: reviews
            version: v3
        spec:
          serviceAccountName: bookinfo-reviews
          containers:
          - name: reviews
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/examples-bookinfo-reviews-v3:1.19.1
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 9080
    ---
    # Productpage services
    apiVersion: v1
    kind: Service
    metadata:
      name: productpage
      labels:
        app: productpage
        service: productpage
    spec:
      ports:
      - port: 9080
        name: http
      selector:
        app: productpage
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: bookinfo-productpage
      labels:
        account: productpage
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: productpage-v1
      labels:
        app: productpage
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: productpage
          version: v1
      template:
        metadata:
          labels:
            app: productpage
            version: v1
        spec:
          serviceAccountName: bookinfo-productpage
          containers:
          - name: productpage
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/examples-bookinfo-productpage-v1:1.19.1
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 9080
            volumeMounts:
            - name: tmp
              mountPath: /tmp
            securityContext:
              runAsUser: 1000
          volumes:
          - name: tmp
            emptyDir: {}
    ---
  2. 执行以下命令,在karmada主集群中部署bookinfo应用。

    kubectl --kubeconfig /etc/karmada/karmada-apiserver.config apply -f bookinfo-karmada.yaml
    说明

    karmada主集群的kubeconfig文件默认保存位置为/etc/karmada/karmada-apiserver.config,如果您在部署主集群时选择了其他安装位置,请将--kubeconfig后的路径替换为实际的路径。

  3. 使用以下内容创建propagation.yaml。

    apiVersion: policy.karmada.io/v1alpha1
    kind: PropagationPolicy
    metadata:
      name: service-propagation
    spec:
      resourceSelectors:
        - apiVersion: v1
          kind: Service
          name: productpage
        - apiVersion: v1
          kind: Service
          name: details
        - apiVersion: v1
          kind: Service
          name: reviews
        - apiVersion: v1
          kind: Service
          name: ratings
      placement:
        clusterAffinity:
          clusterNames:
            - member1
            - member2
    ---
    apiVersion: policy.karmada.io/v1alpha1
    kind: PropagationPolicy
    metadata:
      name: produtpage-propagation
    spec:
      resourceSelectors:
        - apiVersion: apps/v1
          kind: Deployment
          name: productpage-v1
        - apiVersion: v1
          kind: ServiceAccount
          name: bookinfo-productpage
      placement:
        clusterAffinity:
          clusterNames:
            - member1
    ---
    apiVersion: policy.karmada.io/v1alpha1
    kind: PropagationPolicy
    metadata:
      name: details-propagation
    spec:
      resourceSelectors:
        - apiVersion: apps/v1
          kind: Deployment
          name: details-v1
    
        - apiVersion: v1
          kind: ServiceAccount
          name: bookinfo-details
      placement:
        clusterAffinity:
          clusterNames:
            - member2
    ---
    apiVersion: policy.karmada.io/v1alpha1
    kind: PropagationPolicy
    metadata:
      name: reviews-propagation
    spec:
      resourceSelectors:
        - apiVersion: apps/v1
          kind: Deployment
          name: reviews-v1
        - apiVersion: apps/v1
          kind: Deployment
          name: reviews-v2
        - apiVersion: apps/v1
          kind: Deployment
          name: reviews-v3
        - apiVersion: v1
          kind: ServiceAccount
          name: bookinfo-reviews
      placement:
        clusterAffinity:
          clusterNames:
            - member1
            - member2
    ---
    apiVersion: policy.karmada.io/v1alpha1
    kind: PropagationPolicy
    metadata:
      name: ratings-propagation
    spec:
      resourceSelectors:
        - apiVersion: apps/v1
          kind: Deployment
          name: ratings-v1
        - apiVersion: v1
          kind: ServiceAccount
          name: bookinfo-ratings
      placement:
        clusterAffinity:
          exclude:
            - member1
    

    PropagationPolicy的.spec.placement.clusterAffinity表示对某一特定集群的调度限制,如果没有这个限制,任何集群都可以作为调度候选者。

    它有四个字段可以设置。

    配置项

    说明

    LabelSelector

    用于通过标签选择成员集群的过滤器。如果它非空且不为nil,则只会选择与此过滤器匹配的集群。

    FieldSelector

    用于通过字段选择成员集群。如果它非空且不为nil,仅匹配此筛选器的集群将被选择。

    ClusterNames

    您可以设置字段以指定所选集群的ClusterNames

    ExcludeClusters

    您可以设置字段以排除所选集群的ClusterNames

    本示例只使用了ClusterNamesExcludeClusters两个字段,更多关于.spec.placement.clusterAffinity字段的信息,请参见Resource Propagating

  4. 执行以下命令,部署PropagationPolicy。

    kubectl --kubeconfig /etc/karmada/karmada-apiserver.config apply -f propagation.yaml
  5. 分别使用member1集群和member2集群的kubeconfig查看Deployment。

    1. member1

      kubectl --kubeconfig member1 get deployment

      预期输出:

      NAME             READY   UP-TO-DATE   AVAILABLE   AGE
      productpage-v1   1/1     1            1           12m
      reviews-v1       1/1     1            1           12m
      reviews-v2       1/1     1            1           12m
      reviews-v3       1/1     1            1           12m
    2. member2

      kubectl --kubeconfig member2 get deployment

      预期输出:

      NAME         READY   UP-TO-DATE   AVAILABLE   AGE
      details-v1   1/1     1            1           16m
      ratings-v1   1/1     1            1           16m
      reviews-v1   1/1     1            1           16m
      reviews-v2   1/1     1            1           16m
      reviews-v3   1/1     1            1           16m

步骤二:添加虚拟服务和网关规则

  1. 在default命名空间下,使用以下内容创建一个名为bookinfo的虚拟服务。具体操作,请参见管理虚拟服务

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: bookinfo
    spec:
      hosts:
      - "*"
      gateways:
      - bookinfo-gateway
      http:
      - match:
        - uri:
            exact: /productpage
        - uri:
            prefix: /static
        - uri:
            exact: /login
        - uri:
            exact: /logout
        - uri:
            prefix: /api/v1/products
        route:
        - destination:
            host: productpage
            port:
              number: 9080
  2. 在default命名空间下,使用以下内容创建一个名为bookinfo-gateway的网关规则。具体操作,请参见管理网关规则

    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: bookinfo-gateway
    spec:
      selector:
        istio: ingressgateway # use istio default controller
      servers:
      - port:
          number: 80
          name: http
          protocol: HTTP
        hosts:
        - "*"

步骤三:访问验证

  1. 获取入口网关的IP地址。具体操作,请参见获取入口网关地址

  2. 在浏览器地址栏,输入http://{Serverless入口网关的IP地址}/productpage,并多次刷新页面。可以看到页面出现reviews的3个版本,且比例接近1:1:1。虽然review-v3和其他服务不在同一个集群中,也可以正常显示。

    image

    image

    image