Nacos多环境隔离与配置同步管理

3,767 阅读5分钟

前言

本文主要从以下几点来带大家熟悉下 Nacos 多环境下配置管理和服务隔离

  • Nacos 的 Namespace 是什么
  • 业务现状与痛点
  • 环境隔离方案介绍
  • 配置同步管理方案

Nacos 的 Namespace 是什么

Nacos是现阶段比较流行的微服务配置中心注册中心服务组件,其引入了命名空间(Namespace)的概念来进行多环境下配置管理和服务隔离。在团队中每个成员也可以共用一个Nacos服务,通过开辟个人的Namespace空间的方式,达到共享nacos资源。

业务现状与痛点

  1. 每个开发人员本地搭建Nacos,环境不统一不便管理。

    • 解决方案:搭建共享Nacos通过Namespace对开发人员进行环境隔离。
  2. 开发环境、测试环境、生产环境有各自的Nacos,修改配置时要挨个手动修改,很不方便

    • 解决方案:构建gitlab流水线通过脚本调用NacosAPI进行配置同步
  3. 目前配置文件为json格式,修改后无法判断语法是否正确,配置修改完成后缺乏对服务健康状态的判断

    • 解决方案:通过python -m json.tool进行语法校验,通过调用服务接口根据返回值进行健康状态检测。

    下面我们就来一步步解决这些痛点

环境隔离方案介绍

解决这些痛点前首先需要了解一下环境隔离方案。

  • Nacos推荐的面向多租户的方案如下:

    从多个租户的角度来看,每个租户可能会有自己的 namespace,每个租户的配置数据以及注册的服务数据都会归属到自己的 namespace 下,以此来实现多租户间的数据隔离。

    例如分配了三个租户,分别为张三、李四和王五。张三负责A项目,李四负责B项目,王五负责C项目

    分配好了之后,各租户用自己的账户名和密码登录后,创建自己的命名空间。如下图所示:

Nacos 通过 Namespace 来隔离多租户之间的服务和配置,而且它具有很好的扩展性

  • 随着业务变规模大,还可以通过Group进行环境分组

    假设公司发展迅速业务调整,张三负责A项目、B项目、C项目,李四负责D项目、E项目、F项目,王五负责G项目、H项目、I项目,

    而每个项目又分了dev、test、prod三个环境,继续沿用之前的Namespace隔离租户方案,显得有些管理不便,这时候可以在NameSpace中加入Group进行项目环境分组,如图:

  • 但是当业务规模更大的时候项目数>环境数时)可以通过 Group 进行项目分组,如下图:

通过上面的理论分析,可以看出该方案有很好的扩展性。

下面我们通过脚本来实践一下。

配置同步管理方案

1. 开发人员创建共享 nacos

将用户账号写入 users,提交 master 分支后会自动在共享 Nacos 创建命名空间。

通过脚本调用使用Nacos的Api来实现,下面介绍了两个关键API

Nacos API 调研

  • 创建命名空间API

    请求类型 POST

    请求路径 /nacos/v1/console/namespaces

    请求参数(字符串类型)

    • customNamespaceId 命名空间ID(必选)
    • namespaceName 命名空间名(必选)
    • namespaceDesc 命名空间描述

    请求示例:

    curl -X POST 'http://localhost:8848/nacos/v1/console/namespaces'-d 'customNamespaceId=&namespaceName=dev&namespaceDesc='
    
  • 发布配置API

    请求类型 POST

    请求 URL/nacos/v1/cs/configs

    请求参数(字符串类型)

    • tenant 租户信息,对应 Nacos 的命名空间ID字段
    • dataId 配置 ID(必选)
    • group 配置分组(必选)
    • content 配置内容(必选)
    • type 配置类型

    请求示例:

    curl -X POST 'http://127.0.0.1:8848/nacos/v1/cs/configs'-d 'dataId=nacos.example&group=com.alibaba.nacos&content=contentTest'
    
  • 实现代码

    通过循环读取users中的用户来创建Namespace,并读取nacos-conf.json中数据创建配置

    # 自动根据用户创建命名空间
    
    if [ $CI_COMMIT_BRANCH = "master" ]; then
    
        namespace=($(cat users))
    
        for url in ${nacos_url[@]}; do
    
            for ns in ${namespace[@]}; do
    
            echo create namespace:$ns namespace
    
            ## 创建命名空间
    
            curl -X POST "${url}/nacos/v1/console/namespaces" -d "customNamespaceId=${ns}&namespaceName=${ns}&namespaceDesc=${ns}"
    
            echo
    
            done
    
        done    
    
    ## 自动发布配置
    
        namespace=($(cat users))
    
        config=$(cat nacos-conf.json)
    
        dataId=gateway-route.properties
    
        group=DEFAULT_GROUP
    
        for url in ${nacos_url[@]}; do
    
            echo ${url}
    
            echo ${namespace[@]}
    
            for ns in ${namespace[@]}; do
    
                echo ${url}
    
                echo ${namespace[@]}
    
                echo create dataId:$dataId in namespace:$ns group:$group
    
                curl --location --request POST "${url}/nacos/v1/cs/configs?tenant=${ns}&dataId=${dataId}&group=${group}"   --form "content=$config"
    
                echo
    
            done
    
        done
    
    
    
    fi
    

2. 配置修改后提交到分支后发布到对应环境

根据分支绑定到不同环境的变量

  • 实现代码

    if [ $CI_COMMIT_BRANCH = "master" ]; then
    
        export nacos_url=(
    
            nacos.test.com:8848
    
            ...
    
            ...
    
        )
    
        export CHECK_URL=(
    
            http://api-test.yizhoucp.cn/api/lanling/login
    
            ...
    
            ...
    
        )
    
    fi
    

3. 语法检查和健康检查

  • 检查 json 格式是否合法

    示例 gitlab-ci.yml 如下

    stages: 
    
      - deploy-nacos
    
    deploy-nacos:
    
      stage: deploy-nacos
    
      tags: 
    
        - nacos
    
      image: nacos-check:alpine3.14
    
      script:
    
        - cat nacos-conf.json |python -m json.tool
    
        - ./nacos.sh
    
      only:
    
        refs:
    
          - master
    
          - deploy-test
    
          - deploy-prod
    

    此处用的的镜像需包含python与curl。示例 Dockerfile 如下

    FROM python:3.9.9-alpine3.14
    
    RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && apk add --no-cache git curl bash ca-certificates
    
    CMD     ["/bin/sh"]
    
  • 健康检查

    通过请求前面定义好的服务接口,返回字段带有code则视为可用,反之失败。

    ## 健康检查
    
        for CHECK in ${CHECK_URL[@]}; do
    
            echo  -----$CHECK
    
            CMD=`curl  ${CHECK} 2>/dev/null | grep -E 'code' | wc -l`
    
            if [ ${CMD} -eq 1 ]; then
    
                echo "Succ: Check proxy ${CHECK} is succeed."
    
        #        exit 0
    
            else
    
                echo "Fail: check proxy ${CHECK} is failed."
    
                export erro_var=1
    
            fi
    
        done
    
    fi
    
    
    
    # echo $erro_var
    
    
    
    if [ ${erro_var} -eq 1 ]; then
    
        exit 1
    
    fi
    

总结

以上分析了Nacos利用Namespace进行环境隔离实践方案,同时进行了自动配置同步代码实验,达到了预期的要求。

参考与感谢:Nacos官方手册Namespace,endpoint 最佳实践

作者简介:

和光,来自杭州晓宇科技,技术中台运维工程师。

| 本文系晓宇科技技术团队出品,著作权归属晓宇科技技术团队。欢迎出于分享和交流等非商业目的转载或使用本文内容,敬请注明“内容转载自晓宇科技技术团队”。本文未经许可,不得进行商业性转载或者使用。