首页 / 平台管理 / 服务网格 / 网格列表 / 创建服务网格

创建服务网格

在您开始体验 Service Mesh 的各项微服务治理功能之前,管理员需要首先为每一个需要提供微服务治理能力的 Kubernetes 集群,部署包括服务网格控制平面组件 Istiod、业务核心组件 asm-controller 等微服务管理平台所需的所有 Service Mesh 组件,并接入必要的外部组件,使集群具备容器化微服务治理的能力。

服务网格管理功能将部署 Service Mesh 组件流程可视化。管理员只需配置主要参数,即可方便、快捷地执行部署服务网格、修改服务网格配置等操作。

前提条件

操作步骤

  1. 在左侧导航栏中,单击 服务网格 > 网格列表

  2. 单击 创建服务网格

  3. 参考以下说明,配置网格的 基本信息网格配置组件配置

    • 基本信息

      • 请结合待部署服务网格集群的 Kubernetes 版本,选择适配的 Istio 版本。

      • 每个集群只能属于一个服务网格。

      • 当选择的集群是 OpenShift 集群时,网格创建成功后,还需要完成 OpenShift 集群后续配置 才能让该集群具备容器化微服务治理的能力。

    • 全局配置:网格全局配置,将应用于部署网格的所有集群的配置。

      参数 说明
      Elasticsearch 对接 平台提供:对接平台默认部署的 Elasticsearch 组件。
      对接成功后,URL 为 global 集群上部署的 Elasticsearch 的访问地址,不可修改。

      自定义:对接平台外已部署的 Elasticsearch 组件,需配置以下参数:
      URL:Elasticsearch 的访问地址,以 http://https:// 开头。
      保密字典:选择或快速创建 1 个存储了 Elasticsearch 认证信息的保密字典。提示: 您可前往 global 集群的 cpaas-system 命名空间,管理存储了 Elasticsearch 认证信息的保密字典。
      监控系统对接 平台提供:对接已选集群上通过平台部署的监控组件。
      对接成功后,URL 为当前集群上部署的监控组件的访问地址,不可修改。
      提示:对接了 Prometheus 监控系统后,无法聚合不同集群的监控数据,会导致平台上的监控数据显示错误。因此,对接了 Prometheus 监控系统的服务网格,仅可纳管 1 个集群。

      自定义:对接已选集群上通过平台外部署的方式部署的监控组件(例如:为接入集群对接的监控组件),需配置以下参数:
      监控系统类型:监控组件的类型。
      URL:监控组件的访问地址,以 http://https:// 开头。
      保密字典:选择或快速创建 1 个存储了监控组件认证信息的保密字典。提示: 您可前往 global 集群的 cpaas-system 命名空间,管理存储了监控组件认证信息的保密字典。
    • 集群维度配置:仅应用于所选集群的配置。

      参数 说明
      Sidecar 配置 Sidecar 资源配额:创建服务网格后,单一 Sidecar 容器可使用的资源(CPU、内存)的默认限制值(limits)。可根据实际情况修改,但不能超过当前命名空间容器限额(LimitRange)的最大限制值。

      热更新升级:启用后,当 Istio 仅升级了修订版本( v <主版本>.<次版本>.<修订版本>)时,可通过平台以不重启服务 Pod 的方式升级服务的 Sidecar;否则,升级 Sidecar 将会重启服务的 Pod。
      调用链配置 采样率:根据业务需要设置调用数据的采样率,控制 Jaeger 采集集群中数据的比率。
      Redis 配置 注意:如需在数据平面使用 服务限流 功能,需启用并 对接 Redis
      HTTP 重试策略 重试次数:当前集群中 HTTP 协议服务初次调用失败(例如:连接失败、返回 503 状态码等)后,尝试重新发送调用请求的最大次数。
      提示:当前配置为集群级别的全局配置。该配置会被具体服务 路由超时和重试 策略中的 重试次数 覆盖。
    • 网关及其他组件配置

      参数 说明
      节点反亲和 Kubernetes 会根据 节点反亲和 设置将网关容器组调度至符合条件的 部署节点。通过为网关组件设置 节点反亲和 属性,可避免或尽量避免流量被负载至不存在网关组件容器组的节点。
      强制:确保所选的每个 部署节点 上都存在网关组件的容器组。
      期望:Kubernetes 会根据调度算法,尽力将网关组件的容器组均匀地调度在所选的 部署节点 上,但无法保证每个节点上都会存在网关组件的容器组。

      说明:当集群中存在多个网关组件容器组时,负载均衡会根据记录在负载列表中的节点的 NodePort 将流量负载至网关部署节点。
      部署节点 定点部署组件的节点,创建网格时,仅可将组件的容器组调度在选定的节点上。
      实例数 期望运行组件的容器组个数,请依据实际的业务请求量设置。
      自动扩缩容 是否启用组件自动扩缩容功能。
      开启后,需要设置自动扩缩容区间(实例数的 最小值最大值),系统会根据组件需要处理的业务请求量自动扩缩组件的容器组个数。
      资源配额 组件的每个容器实例创建时的资源(CPU、内存)请求值(requests),同时也是容器可用资源的限制值(limits)。请结合实际的业务量和实例数合理设置。
      资源总量 当前配置下,所有组件的容器实例创建时所需的资源(CPU、内存)配额总量。
      当组件启用自动扩缩容时,则按照实例数的最大值进行统计。
  4. 单击 创建
    创建成功后,系统将依次在集群中部署各个组件。在 网格部署 区域单击 ,可查看部署进度。

如何对接 Redis?

平台外 Redis

若待对接的 Redis 是部署在平台外的,请参考如下说明配置相关参数。

参数 说明
部署模式 单节点:部署在单个节点上的 Redis,不具备容灾能力,不建议用于生产环境。
集群-哨兵模式:参见 官方文档
集群-集群模式:参见 官方文档
地址/地址列表 Redis 的访问地址,支持 HTTP/HTTPS 协议地址,输入格式如: <协议可省略>://<IP/域名>:<端口>
提示:输入多个地址,可提升访问地址的可用性,地址之间使用 , 分隔。
MasterName 仅哨兵模式时必填,为主节点的名称。
保密字典 选择或快速创建 1 个存储了 Redis 认证信息(密码)的保密字典。
提示: 您可在 global 集群的 cpaas-system 命名空间中,管理存储了认证信息的保密字典。

平台内 Redis

若您所在的企业已订阅了 Data Services,并通过 Data Services 部署了可对接至网格纳管的集群的 Redis(集群模式、哨兵模式)时,可参考如下步骤及说明获取并配置服务网格集群维度的 Redis 配置

获取 Redis 访问方式

  1. 切换至 Data Services 平台后,在左侧导航栏中选择 Redis

  2. 在左侧集群列表中,选择部署了 Redis 的 集群、命名空间

  3. 单击 Redis 名称

    • 详情信息 页签下,查看 保密字典 可获取 Redis 的访问密码。

    • 访问方式 页签下,可查看对接 Redis 所需的配置信息。

集群维度 Redis 配置说明

根据 Redis 的 部署模式部署位置,参考以下说明,配置服务网格集群维度的 Redis 配置

说明

Redis 部署模式 对接方式 网格对接 Redis 的配置
哨兵模式 同集群 部署模式:集群-哨兵模式。
MasterName:必须输入 mymaster
地址列表:输入 集群内访问 区域展示的 连接地址<内部路由名称>.<Redis 实例所在命名空间名称>:<端口><内部路由的 IP>:<端口>)。
哨兵模式 跨集群 部署模式:集群-哨兵模式。
MasterName:必须输入 mymaster
地址列表:输入 集群外访问 区域展示的 连接地址<Pod IP>:<端口>)。
集群模式 同集群 部署模式:集群-集群模式。
地址列表:输入 集群内访问 区域展示的 连接地址<分片的内部路由名称>.<Redis 实例所在命名空间名称>:<端口>)。
集群模式 跨集群 部署模式:集群-集群模式。
地址列表:输入 集群外访问-通过 Pod 的 NodePort 区域展示的 1 个或多个分片中包含的 Pod 的 Nodeport(<Pod IP>:<端口>)。

OpenShift 集群后续配置

当部署服务网格相关组件的集群为 OpenShift 集群时,服务网格创建成功后,还需参考下文修改集群上的配置,才能让 OpenShift 集群具备容器化微服务治理的能力。

前提条件

集群上服务网格的组件已部署成功。

操作步骤

  1. 登录 OpenShift 集群的跳板机,执行以下命令,指定 istio-cni 镜像所在的仓库地址并拉取镜像。

    [root@bastion ~]$ privateRegistry=10.0.131.247:60080
    [root@bastion ~]$ docker pull  ${privateRegistry}/asm/install-cni:<istio-cni 镜像版本>

    说明: Istio 版本与 istio-cni 镜像版本的适配关系参见下表。

    Istio 版本 istio-cni 镜像版本
    1.16.1 1.16.1-v3.12.4
    1.14.1 1.14.1-v3.12.3
  2. 执行以下命令,切换至 root 用户。

    [root@bastion ~]$ sudo -i
  3. 执行以下命令,通过将 istio-system 命名空间加入 anyuid SCC(security context constraints)组,为命名空间授权。

    oc adm policy add-scc-to-group anyuid system:serviceaccounts:istio-system \
    && oc adm policy add-scc-to-group anyuid system:serviceaccounts:istio-system
  4. 执行以下命令,查询集群中的 IstioOperator 资源,并更新该资源。

    oc get -n istio-system istiooperator

    更新 IstioOperator 资源的以下参数:

    • istioCRName:IstioOperator 的名称,例如:istioCRName=istio

    • privateRegistry:平台的 registry 地址,例如:privateRegistry=10.0.131.247:60080

    • workloadNs:要运行服务的命名空间名称,多个以空格分隔。例如:workloadNs=(asm-ocp-n1 asm-ocp-n2)

  5. 执行以下命令,配置 Prometheus 的访问信息。

    feat_monitoring=`oc get feature monitoring -ojsonpath='{.metadata.name}'`
    
    if [ -z "$feat_monitoring" ]; then
        promPass=`oc get feature prometheus -o=jsonpath='{.spec.accessInfo.prometheusPassword}'`
        promUrl=`oc get feature prometheus -o=jsonpath='{.spec.accessInfo.prometheusUrl}'`
        promUser=`oc get feature prometheus -o=jsonpath='{.spec.accessInfo.prometheusUser}'`
    else
        prom_ns=`oc get feature monitoring -oyaml |grep monitoring.namespace | awk -F : '{print $2}'`
        prom_secret_name=`oc get feature monitoring -ojsonpath='{.spec.accessInfo.database.basicAuth.secretName}'`
        promUser=`oc get -n ${prom_ns} secret ${prom_secret_name} -ojsonpath='{.data.username}' | base64 -d`
        promPass=`oc get -n ${prom_ns} secret ${prom_secret_name} -ojsonpath='{.data.password}' | base64 -d`
        promUrl=`oc get feature monitoring -ojsonpath='{.spec.accessInfo.database.address}'`
    fi
    
    echo $promUser
    echo $promPass
    echo $promUrl
    fail (){
      echo -e "\033[31m $1 \033[0m"; exit 1
    }
    if [[ -z $promUser ]]; then fail "promUser is empty" ;fi
    if [[ -z $promPass ]]; then fail "promPass is empty" ;fi
    if [[ -z $promUrl ]]; then fail "promUrl is empty" ;fi
  6. 执行以下命令,为要运行服务的命名空间授权。

    for ns in ${workloadNs[@]};do
    oc adm policy add-scc-to-group privileged system:serviceaccounts:${ns} \
    && oc adm policy add-scc-to-group anyuid system:serviceaccounts:${ns} \
    && oc -n ${ns} apply -f - <<EOF
    apiVersion: "k8s.cni.cncf.io/v1"
    kind: NetworkAttachmentDefinition
    metadata:
      name: istio-cni
    EOF
    done
  7. 执行以下命令,更新 Istio CR。

    提示:istioCRName=<上文中更新 IstioOperator 资源时为 istioCRName 设置的值>。

    t=`oc get -n istio-system istiooperator ${istioCRName} |egrep -v NAME | wc -l`; if [[ $t == 0 ]]; then fail "istiooperator istio not found" ;fi
    
    kubectl patch -n istio-system istiooperator ${istioCRName} --type='json' -p="[{'op': 'replace', 'path': '/spec/values/cni','value':{'cniBinDir':'/var/lib/cni/bin','cniConfDir':'/etc/cni/multus/net.d','chained':false,'cniConfFileName':'istio-cni.conf','excludeNamespaces':['istio-system','kube-system']}},{'op': 'replace', 'path':'/spec/values/sidecarInjectorWebhook','value':{'injectedAnnotations':{'k8s.v1.cni.cncf.io/networks':'istio-cni'}}}]"
    
    cni_image=`oc get -n istio-system istiooperator ${istioCRName} -ojsonpath='{.spec.values.global.proxy_init.image}' | sed 's/proxyv2/install-cni/'`
  8. 执行 oc edit -n istio-system istiooperator ${istioCRName} 命令修改 istio-system 命名空间中的 istiooperator 资源。

    spec.components 字段下方加入以下内容:

        cni:
          enabled: true
          namespace: kube-system
          k8s:
            overlays:
              - kind: DaemonSet
                name: istio-cni-node
                patches:
                  - path: spec.template.spec.containers[name:install-cni].securityContext.privileged
                    value: true
                  - path: spec.template.spec.containers[name:install-cni].image
                    value: <$cni_image>
  9. 依次执行以下命令,对接服务网格的 Grafana 监控面板。

    t=`oc get -n istio-system cm grafana |egrep -v NAME | wc -l`; if [[ $t == 0 ]]; then fail "configmap grafana not found" ;fi
    
    oc get -n istio-system cm grafana -ojson > grafana_cm.json
    
    echo -e "import json\nwith open('grafana_cm.json','r') as ografanaFile:\n\tografana_data = json.load(ografanaFile);\n\tografana_data['data']['prometheus.yaml']=ografana_data['data']['datasources.yaml'];\n\tografana_data['data']['datasources.yaml']=ografana_data['data']['datasources.yaml'].replace('isDefault: true\\\n  ','')\nwith open('grafana_cm_result.json','w') as dgrafanaFile:\n\tjson.dump(ografana_data,dgrafanaFile)" > patch_grafana.py
    
    python patch_grafana.py
    
    oc apply -f grafana_cm_result.json
    
    # 清理临时脚本,oc apply 命令执行完成后执行
    rm -rf grafana_cm*.json patch_grafana.py
    
    t=`oc get -n istio-system deploy grafana |egrep -v NAME | wc -l`; if [[ $t == 0 ]]; then fail "deploy grafana not found" ;fi
    volData=$(cat <<EOF
    {
        "spec": {
            "template": {
                "spec": {
                    "containers": [{
                        "name": "grafana",
                        "volumeMounts": [{
                            "mountPath": "/etc/grafana/provisioning/datasources/prometheus.yaml",
                            "name": "config",
                            "subPath": "prometheus.yaml"
                        }]
                    }]
                }
            }
        }
    }
    EOF
    )
  10. 执行以下命令,更新 Grafana 的挂载路径。

    kubectl patch -n istio-system deploy grafana --patch "${volData}"
  11. 执行以下命令,在 istio-system 命名空间下,创建 RoleRolebinding 资源。

    说明:该步骤用于为 openshift-monitoring 命名空间中的 prometheus-k8s serviceaccount 授予访问 istio-system 命名空间下相应资源的权限。

    rbacNs=(istio-system ${workloadNs[@]})
    for ns in ${rbacNs[@]};do
    oc -n ${ns} apply -f - <<EOF
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: prometheus-k8s
    rules:
      - verbs:
          - get
          - watch
          - list
        apiGroups:
          - ''
        resources:
          - pods
          - services
          - endpoints
    ---
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: prometheus-k8s
    subjects:
      - kind: ServiceAccount
        name: prometheus-k8s
        namespace: openshift-monitoring
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: prometheus-k8s
    EOF
    
    done
  12. 执行以下命令,关闭 Jaeger oauth。

    t=`oc get -n istio-system jaeger jaeger-prod |egrep -v NAME | wc -l`; if [[ $t == 0 ]]; then fail "jaeger jaeger-prod not found" ;fi
    kubectl patch -n istio-system jaeger jaeger-prod --type='json' -p='[{"op": "add", "path":"/spec/ingress/security","value":"none"}]'
  13. 执行以下命令,为 istio-system 命名空间增加 openshift.io/cluster-monitoring=true 标签。

    kubectl label ns istio-system openshift.io/cluster-monitoring=true
  14. 将以下脚本内容保存为 .sh 文件,并执行脚本(命令:sh <脚本文件名称>.sh)检查集群的配置和组件状态。

    #!bin/bash
    
    istioCRName=`kubectl get -n istio-system istiooperator  --ignore-not-found=true|grep -v NAME | awk '{print $1}' | awk -F"-" 'NF-1==1 {print $0}' | sort -r | head -n 1`
    if [[ -z $istioCRName ]]; then echo -e " \033[31m istioCRName is empty \033[0m ; exit 1" ;fi
    
    feat_monitoring=`oc get feature monitoring -ojsonpath='{.metadata.name}'`
    if [ -z "$feat_monitoring" ]; then
      feature_config=`oc get feature prometheus -ojsonpath='{..spec.accessInfo.prometheusConfig}'`
    else
      feature_config=`oc get feature monitoring -ojsonpath='{..spec.accessInfo.database}'`
    fi
    
    cni_enable=`oc get -n istio-system istiooperator ${istioCRName} -ojsonpath='{..spec.components.cni.enabled}'`
    cni_pod=`oc get -n kube-system po |grep cni`
    grafana_cfg=`oc get -n istio-system cm grafana -oyaml | grep prometheus.yaml`
    grafana_deploy=`oc get -n istio-system deploy grafana -oyaml |grep /etc/grafana/provisioning/datasources/prometheus.yaml`
    istio_prm_role=`oc get -n istio-system role prometheus-k8s |grep -vi name`
    istio_prm_rolebinding=`oc get -n istio-system rolebinding prometheus-k8s |grep -vi name`
    
    name=('feature_config' 'cni_enable' 'cni_pod' 'grafana_cfg' 'grafana_deploy' 'istio_prm_role' 'istio_prm_rolebinding'  )
    checked=("${feature_config}" "${cni_enable}" "${cni_pod}" "${grafana_cfg}" "${grafana_deploy}" "${istio_prm_role}" "${istio_prm_rolebinding}"  )
    
    for(( i=0;i<${#name[@]};i++)) do
    echo ${name[i]};
    if [[ -n "${checked[i]}" ]]; then
      echo -e "\033[32m pass \033[0m"
    else
      echo -e " \033[31m fail \033[0m"
      #exit 1
    fi
    echo ""
    done;