
# 创建MCI
#### 约束限制
- 当前MCI仅支持版本为1.21及以上的CCE Turbo集群、网络模型为underlay的其他Kubernetes集群创建。
- 请提前做好网络规划，保证成员集群间容器网络不冲突，确保ELB实例与容器Pod IP网络可达。若MCI的ELB实例与集群处于不同VPC内，请提前打通VPC间的网络。
- 当为同一Service同时配置MCI与MCS时，该Service将会下发至MCS中配置的下发集群、访问集群以及对应工作负载的部署集群。
 
#### 准备工作
- 如您没有可用的ELB实例，需要先创建ELB实例，具体请参考[创建独享型负载均衡器](https://support.huaweicloud.com/usermanual-elb/elb_lb_000006.html)。该ELB实例需要满足以下条件：
  - ELB为独享型。
  
  - ELB必须支持应用型（HTTP/HTTPS）。
  
  - ELB网络类型必须支持私网（有私有IP地址）。
  
  - 如果ELB与成员集群的网络不在同一VPC内，ELB需要支持开启跨VPC访问的开关。
   
- MCI为跨集群后端工作负载提供统一入口和七层网络访问，因此需要在联邦中提前部署可用的工作负载（Deployment）和服务（Service）。若您无可用工作负载和服务，请参考[无状态负载](https://support.huaweicloud.com/usermanual-ucs/ucs_01_0255.html)和[集群内访问（ClusterIP）](https://support.huaweicloud.com/usermanual-ucs/ucs_01_0271.html)创建。
- 设置集群为underlay网络，支持underlay网络的集群类型请参见[设置集群网络](https://support.huaweicloud.com/usermanual-ucs/ucs_01_0377.html#ucs_01_0377__section191095498203)。
![](https://support.huaweicloud.com/usermanual-ucs/public_sys-resources/note_3.0-zh-cn.png)
若创建MCI实例时，出现报错"policy doesn't allow 'get loadbalancer' to be performed."或"because no identity-based policy allows the xxx action."，表示当前委托权限还未生效，请等待片刻后重试即可，错误出现在事件中则无需关心。
#### 通过控制台YAML创建多集群路由(MCI)
1. 登录[UCS控制台](https://console.huaweicloud.com/ucs/?#/aether/dashboard)，在左侧导航栏中选择"容器舰队"。
2. 在"容器舰队"页签下找到已开通集群联邦的舰队，单击名称进入详情页。
3. 在左侧导航栏中选择"服务与路由"，选择"多集群路由"页签。
4. 在多集群路由页签，单击右上角"YAML创建"，弹出多集群路由(MCI)YAML创建界面。
5. 当前数据选择YAML，在编辑栏进行编辑（根据实际需求调整配置参数）： 
   ```
   apiVersion: networking.karmada.io/v1alpha1
   kind: MultiClusterIngress
   metadata:
     name: nginx-51063
     namespace: default
     annotations:
       karmada.io/elb.id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
       karmada.io/elb.projectid: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
       karmada.io/elb.port: "80"
   spec:
     ingressClassName: public-elb
     rules:
     - http: 
         paths: 
         - backend:
             service:
               name: nginx-14479     # 准备一个名为nginx-14479的联邦service
               port:
                 number: 80     # 端口号为80
           path: /
           pathType: Prefix
   ```
   
   
6. 编辑完成后，单击右下角"确定"，完成多集群路由（MCI）创建。
 
#### 通过Kubectl命令创建MCI对象
1. 使用kubectl连接集群联邦，详细操作请参见[使用kubectl连接集群联邦](https://support.huaweicloud.com/usermanual-ucs/ucs_01_0320.html)。
2. 创建并编辑 mci.yaml 文件，文件内容定义如下所示，参数定义请参见[表1]。
   
   **vi mci.yaml**
   ```
   apiVersion: networking.karmada.io/v1alpha1 
   kind: MultiClusterIngress
   metadata:
     name: nginx-ingress
     namespace: default
     annotations:
       karmada.io/elb.conditions.nginx-svc: 
         '[{ 
             "type": "header", 
             "headerConfig": { 
                 "key":"x-header", 
                 "values": [ 
                 "green" 
                 ] 
             } 
         }]'
       karmada.io/elb.id: 90f9f782-1243-41cc-a57d-6157f6cb85bf
       karmada.io/elb.projectid: 65382450e8f64ac0870cd180d14e684b
       karmada.io/elb.port: "883"              # 端口设置
       karmada.io/elb.health-check-flag.nginx-svc: "on"   # 对应服务的健康检查配置项开关
       karmada.io/elb.health-check-option.nginx-svc: '{"protocol":"TCP"}'   # 对应服务的健康检查配置项
   spec:
     ingressClassName: public-elb
     rules:
     - host: demo.localdev.me
       http:
         paths:
         - backend:
             service:
               name: nginx-svc       # 准备一个名为nginx-svc的联邦service
               port:
                 number: 8080        # 端口号为8080
           path: /web
           pathType: Prefix
   ```
   MCI对象的结构体定义与[networking.kubernetes.io/v1版本Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)一致，不同之处在于后端服务需要填写为联邦Service，即在UCS控制台创建的Service，具体请参见[集群内访问（ClusterIP）](https://support.huaweicloud.com/usermanual-ucs/ucs_01_0271.html)。
   ![](https://support.huaweicloud.com/usermanual-ucs/public_sys-resources/notice_3.0-zh-cn.png)
   在配置MCI文件内容的过程中需要遵守的约束条件如下：
   - apiVersion，kind，name必须指定。
   
   - spec下不允许填写TLS和DefaultBackend字段。
   
   - rules、paths不能为空。
   
   - host必须是DNS名称，不可以是IP地址。
   
   - service中所指定的后端服务必须是存在的、且输入的相关信息（如端口）是正确的，否则会导致访问服务失败。若您已经创建了参数信息错误的MCI对象，请参考[4]中的命令更新该MCI对象。
   
   - paths中，配置的高级转发策略（karmada.io/elb.conditions.{serviceName}）越多的后端（backend）在paths中的位置应该越靠前。因为backend在paths中配置的位置越靠前，其转发优先级越高。 示例：如果为后端X配置两条转发策略a和b，为后端Y配置一条转发规则a，则此时paths中X的配置顺序应在Y之前，否则，同时符合a、b两条转发规则的流量将按照优先级顺序全部转发至Y中。
     
   
   - backend下不允许填写resource字段。
   
   - path值需要是绝对路径；不合法的path值：invalidPathSequences = \[\]string{"//", "/./", "/../", "%2f","%2F"}，invalidPathSuffixes = \[\]string{"/..", "/."}。
   
   - pathType合法值：Exact、Prefix、ImplementationSpecific。
   
   - 在默认配置下，Service名称的长度限制最长支持50个字符。
    
    表1关键参数说明 
   | 参数                                               | 是否必填 | 参数类型                                                                                                                     | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
   |:---|:---|:---|:---|
   | karmada.io/elb.id                                | 是    | String                                                                                                                   | MCI关联的elb的id，不允许为空。 取值范围：1-32个字符。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
   | karmada.io/elb.projectid                         | 是    | String                                                                                                                   | MCI关联的elb所属的项目ID。获取方法请参见[获取项目ID](https://support.huaweicloud.com/api-ucs/ucs_api_0018.html)。 取值范围：1-32个字符。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
   | karmada.io/elb.port                              | 否    | String                                                                                                                   | MCI关联的elb的端口，不填时默认为80。 取值范围：1-65535。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
   | karmada.io/elb.health-check-flag.{serviceName}   | 否    | String                                                                                                                   | 是否启用健康检查，可选值为： - on：开启  - off：不开启   不填写时默认为off。 说明： - 该标签为"karmada.io/elb.health-check-flag.{serviceName}"，仅对对应的service生效；  - 在annotation开启健康检查配置的情况下，Service名称的长度不应超过41个字符。                                                                                                                                                                                                                                                                                                           |
   | karmada.io/elb.health-check-option.{serviceName} | 否    | [HealthCheck] Object                                                                     | 健康检查参数，详情请参见[HealthCheck]。{serviceName}请修改为联邦Service的名称。 说明： - 健康检查参数配置示例：   karmada.io/elb.health-check-option.nginx-svc: '{"protocol":"TCP","delay":"5","connect_port":"80","timeout":"1","max_retries":"1","path":"/wd"}' - 在annotation开启健康检查配置的情况下，Service名称的长度不应超过39个字符。  - 创建mci，配置健康检查，协议是TCP时，健康检查path参数不生效。  - {serviceName}必须与后端服务配置的name一致。                                                                                                  |
   | karmada.io/elb.conditions.{serviceName}          | 否    | Array of [Condition] Object                                                              | 高级转发策略，详情请参见[Condition]。 - {serviceName}请修改为联邦Service的名称。  - Service名称的长度不应超过48个字符。  - Service规则不可重复。  - Service规则总数不可大于10条。  - Service选择必须与转发规则配置中的Service一致。                                                                                                                                                                                                                                                                                          |
   | karmada.io/elb.lb-algorithm.{serviceName}        | 否    | String                                                                                                                   | 转发算法： - ROUND_ROBIN：加权轮询算法。  - LEAST_CONNECTIONS：加权最少连接算法。  - SOURCE_IP：源IP算法。   不填写时默认为ROUND_ROBIN。 - {serviceName}请修改为联邦Service的名称。  - Service名称的长度不应超过46个字符。                                                                                                                                                                                                                                                                          |
   | karmada.io/elb.keepalive_timeout                 | 否    | string                                                                                                                   | 客户端连接空闲超时时间，单位为秒。当一直未请求的时间超过配置值，负载均衡会暂时中断当前连接，直到下一次请求时再重新建立新的连接。 不填写时默认为60s。 取值范围：0-4000s                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
   | karmada.io/elb.client_timeout                    | 否    | string                                                                                                                   | 等待客户端请求超时时间，单位为秒。 不填写时默认值为60s。 取值范围：1-300s                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
   | karmada.io/elb.member_timeout                    | 否    | string                                                                                                                   | 等待后端服务器响应超时时间，单位为秒。请求转发后端服务器后，若未响应时间超过配置值，负载均衡将终止等待，并返回HTTP 504错误码。 不填写时默认为60s。 取值范围：1-300s                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
   | ingressClassName                                 | 是    | String                                                                                                                   | ingressClass名称。取值必须为public-elb。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
   | host                                             | 否    | String                                                                                                                   | - 为服务访问域名配置，默认为""，表示域名全匹配。请确保所填写的域名已注册并备案，一旦配置了域名规则后，必须使用域名访问。  - 需满足ELB侧HostName校验规则:至少包含两个字符串,字符串之间以点分隔,字符串只能由英文字母、数字、中划线、小数点和\*组成。字符串必须以英文字母、数字或\*开头，不能以中划线结尾。\*只能出现在开头且必须以\*.开始                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
   | backend                                          | 否    | [Backend](https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressBackend) Object | 后端，是Service和端口名称的组合。对于发往MCI的 HTTP和HTTPS请求，如果与规则中的主机和路径匹配，则会被发送到所列出的后端。 注意： 后端在paths中的配置顺序决定了策略的转发优先级。 示例：如果为后端X配置两条转发策略a和b，为后端Y配置一条转发规则a，则此时paths中X的配置顺序应在Y之前，否则，同时符合a、b两条转发规则的流量将按照优先级顺序全部转发至Y中。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
   | path                                             | 是    | String                                                                                                                   | 路由路径，您可以自定义设置。所有外部访问请求需要匹配host和path。 说明： 此处添加的访问路径要求后端应用内存在相同的路径，否则转发无法生效。 例如，Nginx应用默认的Web访问路径为"/usr/share/nginx/html"，在为Ingress转发策略添加"/test"路径时，需要应用的Web访问路径下也包含相同路径，即"/usr/share/nginx/html/test"，否则将返回404。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
   | pathType                                         | 是    | String                                                                                                                   | 路径类型。 - ImplementationSpecific: 正则匹配，请求的URL和设定的URL正则表达式匹配。  - Exact：精确匹配 URL 路径，且区分大小写。  - Prefix：前缀匹配，且区分大小写。该方式是将URL路径通过"/"分隔成多个元素 ，并且对元素进行逐个匹配。 如果URL中的每个元素均和路径匹配，则说明该URL的子路径均可以正常路由。 说明： - Prefix匹配时每个元素均需精确匹配，如果URL的最后一个元素是请求路径中最后一个元素的子字符串，则不会匹配 。例如：/foo/bar匹配/foo/bar/baz，但不匹配/foo/barbaz。  - 通过"/"分隔元素时，若URL或请求路径以"/"结尾，将会忽略结尾的"/"。例如：/foo/bar会匹配/foo/bar/。      关于Ingress路径匹配示例，请参见[示例](https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/#示例)。 |
      
    表2HealthCheck参数说明 
   | 参数           | 是否必填 | 参数类型   | 描述                                                                                                                                                           |
   |:---|:---|:---|:---|
   | protocol     | 否    | String | 健康检查使用的协议，支持TCP/HTTP，默认值是TCP。                                                                                                                                |
   | connect_port | 否    | Int    | 健康检查使用的端口。取值范围\[1，65535\]，为可选参数。 说明： 默认使用后端服务器默认业务端口进行健康检查。指定特定端口后，使用指定的端口进行健康检查。                  |
   | delay        | 否    | Int    | 健康检查的延迟时间，以秒为单位，1-50，默认值是5秒。                                                                                                                                 |
   | timeout      | 否    | Int    | 健康检查的超时时间，以秒为单位，1-50，默认值是10秒。                                                                                                                                |
   | path         | 否    | String | 健康检查的请求URL，当type为HTTP/HTTPS时生效。 以"/"开头，默认为"/"。支持使用字母、数字和短划线（-）、正斜线（/）、半角句号（.）、百分号（%）、半角问号（?）、井号（#）和and（\&）以及扩展字符集。长度为1-80个字符。 |
   | max_retries  | 否    | Int    | 最大重试次数，取值范围1-10，默认值是3次。                                                                                                                                      |
      
    表3Condition参数说明 
   | 参数           | 是否必填 | 参数类型                                                     | 描述                                                               |
   |:---|:---|:---|:---|
   | type         | 是    | String                                                   | 高级转发策略类型，当前仅支持header。                                            |
   | headerConfig | 是    | [headerConfig] Object | 高级转发策略对象，详情请参见[headerConfig]。 |
      
    表4headerConfig参数说明 
   | 参数     | 是否必填 | 参数类型     | 描述                                                                                                                                                                                                                                                                                                                              |
   |:---|:---|:---|:---|
   | key    | 是    | String   | - 转发Header头。  - 长度限制1-40字符，只允许包含字母、数字、短划线和下划线。  - key值不可重复。                                                        |
   | values | 是    | String数组 | - 转发Header头对应的值。  - 长度限制1-128字符，不支持空格， 双引号，支持以下通配符：\*（匹配0个或更多字符）和？（正好匹配1个字符）。  - values可以有多个值，多个值之间不可重复，不可只部分正确。   |
      
   
   
3. 执行如下命令创建MCI对象。 
   **kubectl apply -f mci.yaml**
   回显如下。
   ```
   multiClusterIngress.networking.karmada.io/nginx-ingress created
   ```
   
   
4. 创建完成后，可以执行如下命令操作MCI对象。其中nginx-ingress为MCI对象的名称。
   
   - 获取MCI对象：**kubectl get mci nginx-ingress**
   
   - 更新MCI对象：**kubectl edit mci nginx-ingress**
   
   - 删除MCI对象：**kubectl delete mci nginx-ingress**
   
   
   
   
 
#### 通过MCI访问服务
MCI对象创建成功后，您可以通过 **http://IP:port/path**访问后端工作负载，其中IP:port为MCI关联ELB的IP和端口，path为MCI对象中定义的路径。
MCI对象中还可以设置外部域名，这样您就可以通过域名来访问到ELB，进而访问到后端服务。
```
spec:
   rules:
   - host: www.example.com       # 域名
     http:
       paths:
       - path: /
         backend:
           serviceName: nginx    # 准备一个名为nginx的联邦service
           servicePort: 80       # 端口号为80
```
![](https://support.huaweicloud.com/usermanual-ucs/public_sys-resources/note_3.0-zh-cn.png)
- 域名访问依赖于域名解析，需要您将域名解析指向ELB实例的IP地址，例如您可以使用[云解析服务 DNS](https://www.huaweicloud.com/product/dns.html)来实现域名解析。
- 若访问服务失败，请参考[通过MCI访问服务失败，如何排查？](https://support.huaweicloud.com/ucs_faq/ucs_faq_0067.html)。
 
