本文将引导您使用容器服务部署SpringCloud微服务,演示使用的服务包括一个注册中心、一个网关和两个独立的Web服务以及一个MySQL数据库。网关和Web服务会注册到注册中心eureka,由网关提供统一访问入口。Web服务使用Kubernetes的服务发现与MySQL通信,而不是eureka。

# 前提

各个微服务组件的容器镜像需要提前的打包好,详细过程可以参照 从源码构建镜像以及上传

演示所用项目代码可以在 gitlab (opens new window) 上找到。

# 网络拓扑图

在演示所用的微服务系统中,用户的请求由网关转发给应用app1或app2。另外app1中有远程调用app2,app2访问数据库的操作。

# 部署与验证

# 创建配置项

通过将程序的配置信息保存为配置项,可以灵活地修改程序配置而无需重新打包。因此我们将4个组件的application.yml内容写到配置项中。

  1. 点击配置>配置项,选择新建配置项

  2. 填写名称eureka-server。

  3. 选择相应集群、命名空间。

  4. 点击添加,新建一个配置数据,键为application.yml,将eureka组件的application.yml贴入其中,点击创建

    如果您的程序采用properties格式配置文件,用法相同。

为使eureka正常工作,需要对配置文件进行一定修改,修改后的基本配置如下,将整个文件内容粘贴到配置数据的“值”区域。

server:
  port: 9999
spring:
  application:
    name: eureka-server
eureka:
  instance:
    hostname: eureka-server
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://eureka-server:9999/eureka/
  server:
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 20000

同理,为网关和两个应用创建配置项gateway、app1、app2。

  • gateway
server:
  port: 8080
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: TO_APP1
          uri: lb://APP1
          predicates:
            - Path=/app1/**
          filters:
            - StripPrefix=1
        - id: TO_APP2
          uri: lb://APP2
          predicates:
            - Path=/app2/**
          filters:
            - StripPrefix=1
eureka:
  instance:
    prefer-ip-address: true #指定向eureka上报地址时使用IP地址
  client:
    service-url:
      instance-id: ${spring.application.name}:${server.port}
      defaultZone: http://eureka-server:9999/eureka/ #指定eureka服务器地址
  • app1
server:
  port: 8080
spring:
  application:
    name: app1
eureka:
  instance:
    prefer-ip-address: true
  client:
    service-url:
      instance-id: ${spring.application.name}:${server.port}
      defaultZone: http://eureka-server:9999/eureka/
  • app2
server:
  port: 8080
spring:
  application:
    name: app2
  datasource:
    # 注意这里mysql的url,使用的是Kubernetes Service的格式
    url: jdbc:mysql://mysql.default.svc.cluster.local:3306/user?serverTimezone=UTC
    username: root
    password: rootroot
    driver-class-name: com.mysql.cj.jdbc.Driver
eureka:
  instance:
    prefer-ip-address: true
  client:
    service-url:
      instance-id: ${spring.application.name}:${server.port}
      defaultZone: http://eureka-server:9999/eureka/

同理,为gateway、app1和app2创建配置项。

# 创建MySQL中间件

通过容器服务内的模板市场,可以快速创建常用中间件。接下来为您演示使用模板市场创建MySQL实例。

  1. 在左侧导航栏中点击模板市场>官方模板

  2. 开始安装MySQL,点击安装

  • 名称填入mysql
  • 选择模板版本。
  • 选择部署集群。
  • 选择命名空间。
  • 配置工作负载均衡。
  • root密码设置为rootroot,初始化数据库设置为user,点击下一步
  • 最后为MySQL中间件配置访问方式,这里选择‘集群内访问’即可。

注意 MySQL中间件的名称、root密码和初始化数据库需要与配置项app2中所写保持一致,否则app2将无法顺利连接数据库

# 创建工作负载

  1. 创建eureka的工作负载,点击工作负载>无状态>创建无状态工作负载

  2. 填写基本信息。

    • 填写工作负载名称。
    • 选择集群和命名空间。
    • 实例数目1。
    • 可以添加描述,点击下一步进入容器设置。
  3. 容器设置基本配置。

    • 填写容器名称。
    • 在配置中,选择镜像及镜像版本。
    • 配置容器规格。
    • 在存储卷的配置中,添加一个存储卷。选择存储类型,选择配置项。

    在挂载规则中,子路径留空,挂载路径选择容器中jar包所在位置下的config/application.yml,在演示所用的镜像中,jar包所在位置为容器镜像的/usr/apps路径,因此挂载路径是/usr/apps/config。

  4. 点击下一步,为工作负载添加一个Service,便于其他组件根据域名地址注册到eureka。

    • Service名称和eureka配置项的中service-url.defaultZone所使用的域名保持一致。因此该Service名称为eureka-server。
    • 访问类型集群内访问,Service访问端口和容器端口相同,都是9999。

  5. 最后点击创建按钮,提交创建任务。

接下来,为网关、app1和app2创建工作负载,流程与上述类似,不再赘述。唯一区别的点在于,第三步不创建Service。

# 创建Service

现在的网关组件,只能在集群内部访问,在实际应用中,网关应该对外提供服务。接下来,我们将为网关创建Service,使其将服务暴露出来。

  1. 点击网络管理>Service>添加Service.

  2. 选择访问类型。

  3. 输入名称。

  4. 选择集群和命名空间。

  5. 选择关联的工作负载为,按需选择自动创建或者已有负载均衡。

  6. 将访问端口80映射到容器端口8080。

创建成功后,查看SLB公网访问地址:

# 验证

提示:

负载均衡绑定弹性IP需要一定时间,请确保Service api-gateway的外部地址显示不为空之后再继续验证操作。

打开浏览器,输入网址http://api-gateway外部IP/app1/test1/get,页面正常显示,再输入网址http://api-gateway外部IP/app2/test2/get,页面正常显示。表明请求正确从网关转发到应用app1和app2,说明服务间通信正常。

接下来的验证操作,需要使用命令行进行。

打开命令行窗口,键入如下命令:

curl 'http://api-gateway外部IP/app1/test1/post' -X POST -H 'Content-Type: application/json' --data '{"from":"curl"}'

服务正常响应。

接下来验证服务间调用。

curl 'http://api-gateway外部IP/app1/to/test2/post' -X POST -H 'Content-Type: application/json' --data '{"from":"curl"}'

服务正常响应。

最后验证数据库访问。

curl 'http://api-gateway外部IP/app2/db/install' -X POST
curl 'http://api-gateway外部IP/app2/db/users'
curl 'http://api-gateway外部IP/app2/db/users' -X POST -H 'Content-Type: application/json' --data '{"name": "u1", "age": 31}'
curl 'http://api-gateway外部IP/app2/db/users'

可以看到,表创建、表查询和表添加都正常响应。

# 结语

本文演示了将Spring Cloud微服务部署到容器服务中的最小配置,无需更改代码即可将Spring Cloud微服务接入到Kubernetes集群中。在兼顾Spring Cloud微服务框架的前提下,实现容器化部署,同时为您展示了Kubernetes提供的部分特性,例如服务发现和配置管理。