通过命令行管理多集群服务
通过多集群服务,让您无需创建负载均衡,即可实现Kubernetes服务的跨集群访问。本文通过示例介绍如何在主控实例上创建ServiceExport、ServiceImport等资源来管理多集群服务,实现Kubernetes服务的跨集群访问。
前提条件
已从ACK One控制台获取主控实例的KubeConfig,并通过kubectl连接至主控实例。
主控实例已添加多个关联集群。具体操作,请参见添加关联集群。
已确保关联集群版本为1.21及以上版本。
已安装AMC命令行工具。具体操作,请参见AMC命令行帮助。
概述
通过多集群服务实现Kubernetes服务的跨集群访问,打破了多集群服务访问的边界。多集群服务示例如下图所示。

使用多集群主控实例的应用分发能力,管理员通过链路0在主控实例上创建应用相关资源,包含Namespace、Deployment、和Service,并创建应用分发规则将应用资源通过链路1分发到ACK Cluster 1上。
管理员通过链路0在主控实例上创建多集群服务Service Export和Service Import,并创建应用分发规则将Service Export分发到ACK Cluster 1上,分发Service Import到ACK Cluster 2上。
在ACK Cluster 2上,Client Pod跨集群访问ACK Cluster 1上的Service1。
步骤一:创建服务提供者相关资源
如果您的服务提供者集群Cluster 1已经部署了Kubernetes服务和相关资源,可以跳过此步骤,只需在后续创建多集群服务ServiceExport和Service Import资源时修改相应的资源名称,具体操作,请参见修改和删除多集群服务。
执行以下命令,创建服务提供者命名空间。
示例的命名空间为
provider-ns
。kubectl create ns provider-ns
执行以下命令,获取关联集群。
kubectl amc get managedclusters
预期输出:
Name Alias HubAccepted c984b0**** cluster2 true # 示例中的服务消费者集群。 cc36f4**** cluster1 true # 示例中的服务提供者集群。
创建服务提供者Kubernetes服务和相关的Deployment等资源。
使用以下内容,创建app-meta.yaml文件,包括Kubernetes服务、相关的Deployment资源和分发规则。
apiVersion: v1 # 服务提供者。 kind: Service metadata: name: service1 namespace: provider-ns spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: web-demo sessionAffinity: None type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: web-demo name: web-demo namespace: provider-ns spec: replicas: 2 selector: matchLabels: app: web-demo template: metadata: labels: app: web-demo spec: containers: - image: acr-multiple-clusters-registry.cn-hangzhou.cr.aliyuncs.com/ack-multiple-clusters/web-demo:0.4.0 name: web-demo env: - name: ENV_NAME value: cluster1-beijing --- apiVersion: core.oam.dev/v1beta1 kind: Application metadata: name: web-demo # 定义应用包含的资源,以及分发规则。 namespace: provider-ns annotations: app.oam.dev/publishVersion: version1 spec: components: - name: web-demo type: ref-objects properties: objects: - resource: deployment name: web-demo - resource: service name: service1 policies: - type: topology name: cluster1 properties: clusters: ["cc36f4****"] # 资源的分发目标,请替换为完整的集群ID。
执行以下命令,将资源下发到主控实例,进而下发到关联集群。
kubectl apply -f app-meta.yaml
执行以下命令,查看应用部署情况。
kubectl get app web-demo -n provider-ns
预期输出:
NAME COMPONENT TYPE PHASE HEALTHY STATUS AGE web-demo web-demo ref-objects running true Ready:2/2 34s
执行如下命令,获取关联集群的资源运行状态。
kubectl amc get deployment,service -n provider-ns -m cc36f4**** # 资源的分发目标,请替换为完整的集群ID。
预期输出:
Run on ManagedCluster cc36f4**** (cluster1) NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/web-demo 2/2 2 2 101s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/service1 ClusterIP 172.16.39.201 <none> 80/TCP 101s
步骤二:创建多集群服务
使用以下内容,创建ServiceExport资源,指定需要开放多集群访问的Kubernetes服务。
apiVersion: multicluster.x-k8s.io/v1alpha1 kind: ServiceExport metadata: name: service1 # 名称与待开放的Kubernetes服务名称相同。 namespace: provider-ns # 与待开放的Kubernetes服务在同一个命名空间。
ServiceExport为新增自定义资源,会分发到服务提供者集群,定义提供者集群需要开放的Kubernetes服务。具体的参数说明如下表所示。
参数
说明
metadata.name
待开放的Kubernetes服务名称。
metadata.namespace
待开放的Kubernetes服务所在的命名空间。
使用以下内容,创建ServiceImport资源。
apiVersion: multicluster.x-k8s.io/v1alpha1 kind: ServiceImport metadata: name: service1 namespace: provider-ns spec: ports: # 与待开放的Kubernetes服务相同。 - port: 80 protocol: TCP type: ClusterSetIP
ServiceImport为新增自定义资源,会分发到服务消费者集群,客户端通过此资源跨集群访问Kubernetes服务。以上代码示例中ServiceImport的
spec
字段仅定义了部分参数。关于spec
完整参数说明如下表所示。参数
说明
metadata.name
名称与待开放的Kubernetes服务名称相同。
metadata.namespace
命名空间名称与待开放的Kubernetes服务命名空间一致。
spec. ports. name
Port名称。需要与待开放的Kubernetes服务相应字段一致。
spec. ports. protocol
协议。需要与待开放的Kubernetes服务相应字段一致。
spec. ports. appProtocol
应用协议。需要与待开放的Kubernetes服务相应字段一致。
spec. ports. port
Port。需要与待开放的Kubernetes服务相应字段一致。
spec. ips
服务VIP。由主控实例分配,无需填写。
spec. type
支持
ClusterSetIP
和Headless
。当待开放的Kubernetes服务的ClusterIP
为None
时,表示服务为Headless
服务,设置type
为Headless
。否则,设置type
为ClusterSetIP
。spec. sessionAffinity
会话关联,支持
ClientIP
和None
。需要与待开放的Kubernetes服务相应字段一致。spec. sessionAffinityConfig
会话关联配置。需要与待开放的Kubernetes服务相应字段一致。
使用以下内容,创建分发规则mcs-service-policy.yaml,向关联集群分发ServiceExport和ServiceImport资源。
apiVersion: core.oam.dev/v1beta1 kind: Application metadata: name: amcs-export-service1 namespace: provider-ns labels: amcs: export amcs-service: service1 annotations: app.oam.dev/publishVersion: version1 spec: components: - name: export-service type: ref-objects properties: objects: - resource: serviceexport #引用ServiceExport资源。 name: service1 policies: - type: topology name: export-clusters properties: clusters: ["cc36f4****"] #向服务提供者集群Cluster 1分发ServiceExport资源。 --- apiVersion: core.oam.dev/v1beta1 kind: Application metadata: name: amcs-import-service1 namespace: provider-ns labels: amcs: import amcs-service: service1 annotations: app.oam.dev/publishVersion: version1 spec: components: - name: import-service type: ref-objects properties: objects: - resource: serviceimport #引用ServiceImport资源。 name: service1 policies: - type: topology name: import-clusters properties: clusters: ["c984b0****"] #向服务消费者集群Cluster 2分发ServiceImport资源。
执行以下命令,部署多集群服务。
kubectl apply -f mcs-service-policy.yaml
执行以下命令,查看分发资源状态。
kubectl amc get serviceexport,serviceimport -n provider-ns -m all
预期输出:
Run on ManagedCluster c984b0**** (cluster2) NAME TYPE IP AGE serviceimport.multicluster.x-k8s.io/service1 ClusterSetIP ["172.xx.xx.xx"] 65s Run on ManagedCluster cc36f4**** (cluster1) NAME AGE serviceexport.multicluster.x-k8s.io/service1 65s
由预期输出看到:ServiceExport资源分发到服务提供者集群Cluster 1,ServiceImport资源分发到服务消费者集群Cluster 2。
步骤三:访问多集群服务
在服务消费者集群Cluster 2中的Client Pod可以通过以下两种方式访问服务提供者集群Cluster 1中的Service 1。
方式一:通过新的Service名称访问
服务消费者集群Cluster 2创建ServiceImport后,主控实例会创建一个以amcs-
为前缀的Kubernetes服务代表多集群Service。在服务消费者集群Cluster 2的Client Pod,可以通过访问amcs-service1.provider-ns
来访问服务提供者集群Cluster 1中的Service 1。
在主控实例上执行如下命令,获取相关Service信息。
kubectl amc get service -n provider-ns -m all
预期输出:
Run on ManagedCluster c984b0**** (cluster2) NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE amcs-service1 ClusterIP 172.xx.xx.xx <none> 80/TCP 26m Run on ManagedCluster cc36f4**** (cluster1) NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service1 ClusterIP 172.xx.xx.xx <none> 80/TCP 169m
在服务消费者集群Cluster 2的Client Pod上执行如下命令,访问服务提供者集群Cluster 1中的Service 1。
curl amcs-service1.provider-ns
方式二:通过新的Service域名访问
在服务消费者集群Cluster 2中安装或升级CoreDNS,版本要求1.9.3及以上。具体操作,请参见CoreDNS和管理组件。
修改CoreDNS组件的配置Corefile。
执行如下命令,修改CoreDNS组件的ConfigMap文件。
kubectl edit configmap coredns -n kube-system
在Corefile文件中新增一行配置项
multicluster clusterset.local
,支持多集群服务域名解析。apiVersion: v1 data: Corefile: | .:53 { errors health { lameduck 15s } ready multicluster clusterset.local #增加配置项,支持多集群服务域名解析。 kubernetes cluster.local in-addr.arpa ip6.arpa { pods verified ttl 30 fallthrough in-addr.arpa ip6.arpa } ... } kind: ConfigMap metadata: name: coredns namespace: kube-system
在服务消费者集群Cluster 2的Client Pod上执行如下命令,访问服务提供者集群Cluster 1中的Service 1。
服务消费者集群Cluster 2上创建ServiceImport之后,服务提供者集群Cluster 1会为多集群服务增加
clusterset.local
域名。curl service1.provider-ns.svc.clusterset.local
(可选)通过修改服务消费者集群Cluster 2中Client Pod的
dnsConfig.searches
,访问多集群服务。在Client Pod的
dnsConfig.searches
字段中增加搜索clusterset.local
的域名。apiVersion: apps/v1 kind: Deployment metadata: name: client-pod namespace: consumer-ns spec: ... template: ... spec: dnsPolicy: "ClusterFirst" dnsConfig: searches: #dnsConfig,增加搜索clusterset.local域名。 - svc.clusterset.local - clusterset.local - consumer-ns.svc.cluster.local - svc.cluster.local - cluster.local containers: - name: client-pod ...
执行如下命令,访问多集群服务。
curl service1.provider-ns
修改和删除多集群服务
修改多集群服务
修改创建ServiceExport和创建ServiceImport中的ServiceExport和ServiceImport资源。
修改分发规则中的
app.oam.dev/publishVersion
,重新下发ServiceExport和ServiceImport资源。
删除多集群服务
执行以下命令,删除多集群服务分发规则。
kubectl delete application amcs-export-service1 -n provider-ns kubectl delete application amcs-import-service1 -n provider-ns
执行以下命令,删除ServiceExport资源。
kubectl delete serviceexport service1 -n provider-ns
执行以下命令,删除ServiceImport资源。
kubectl delete serviceimport service1 -n provider-ns