亚马逊AWS官方博客

Spring Cloud 的云原生迁移 – AWS 上的混合部署架构(下篇)

简介

在前面的文章中,对 Spring Cloud 在 AWS 上的混合部署架构已经进行了讨论,并完成了 Eureka 及 API Gateway 的部署。在本文中,我们将讨论在 AWS 托管的 Kubernetes 服务EKS上部署 Spring Cloud 的实际业务功能模块。

 

架构回顾

 

EKS为Spring Cloud部署带来的好处

EKS的特点

Amazon Elastic Kubernetes Service (Amazon EKS) 是一项完全托管的 Kubernetes 服务。由于EKS把安全性、可靠性和可扩展性作为产品最重要的特性进行实现,在公有云上使用Kubernetes技术的多数大型客户,都使用 EKS运行他们最敏感的任务关键型应用程序。

同时,EKS 与诸如 Amazon CloudWatch、Auto Scaling Group、AWS Identity and Access Management (IAM) 和 Amazon Virtual Private Cloud (VPC) 之类的服务深度集成,为客户带来监控、扩展和负载平衡应用程序的无缝体验。

最后,EKS经认证与 Kubernetes 一致,因此客户可以利用社区中开源工具的所有优势。任何标准 Kubernetes 应用程序可轻松地迁移到 EKS,而无需重构代码。

(EKS托管架构)

 

Amazon VPC CNI 插件

在Kubernetes的网络模型中,要求所有的网络插件实现必须满足如下要求:

  • 所有的 Pod 可以与任何其他 Pod 直接通信,无需使用 NAT 映射(network address translation)
  • 所有节点可以与所有 Pod 直接通信,无需使用 NAT 映射
  • Pod 内部获取到的 IP 地址与其他 Pod 或节点与其通信时的 IP 地址是同一个

 

Amazon VPC CNI插件的实现方式是使Kubernetes的Pod获取VPC的私有IP地址。此实现方式不但完全满足Kubernetes网络模型的要求;不使用overlay网络可以使Pod的通信效率和在物理网络中相当;同时由于Pod持有的是和EC2相同的VPC私有IP,因此Pod与EC2的网络地位一致,可以直接通信。这些特性使得用Spring Cloud框架开发的业务模块部署于EKS cluster中,与部署在EC2中的Eureka、API Gateway进行交互时,不会遇到困难,同时还保持了通信的最高效率。

 

在EKS Cluster中部署Spring Cloud的业务模块

前置条件

  • Create a Workspace
  • Create an SSH key
  • Install Kubernetes Tools
  • Create an IAM role for your Workspace
  • Attach the IAM role to your Workspace
  • Update IAM settings for your Workspace
  • Install eksctl

Note: 前置条件过程请参考AWS EKS官方workshop: https://eksworkshop.com/eksctl/

 

创建EKS群集

 

创建的EKS群集放置在与Eureka、API Gateway 相同的VPC中。如下为示例群集配置文件:

---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: eksworkshop-eksctl
  region: us-east-2
  version: "1.17"

vpc:
  subnets:
    private:
      us-east-2a: { id: subnet-e2f1ea8a }
      us-east-2b: { id: subnet-28cd9c52 }
      us-east-2c: { id: subnet-a8ca72e4 }

managedNodeGroups:
- name: nodegroup
  desiredCapacity: 3
  ssh:
    allow: true
    publicKeyName: <SSH public key name>

# To enable all of the control plane logs, uncomment below:
# cloudWatch:
#  clusterLogging:
#    enableTypes: ["*"]

secretsEncryption:
  keyARN: <kms key ARN>

 

 

 

群集创建命令:

$ eksctl create cluster -f < ClusterConfig >.yaml

 

调整EKS群集的安全组

 

通过eksctl创建的EKS群集,worker node上的安全组默认没有开放VPC内其他EC2的访问权限。手工调整对应的安全组,添加一条允许其他Spring Cloud基础设施的安全组访问的条目。

 

安装Helm

 

Helm是一个Kubernetes的包和应用管理工具。使用Helm可以极大地简化Kubernetes上标准应用的安装。

Helm的安装请参考链接:https://www.eksworkshop.com/beginner/060_helm/helm_intro/install/

 

安装Metrics Server

Metrics Server是Kubernetes中的核心监控指标实现,替代了heapster。Horizontal Pod Autoscaler所依赖的监控数据,就是由Metrics Server提供。下面示例为使用Helm部署Metrics Server:

# create the metrics-service namespace
$ kubectl create namespace metrics

# deploy the metrics-server
$ helm install metrics-server \
    stable/metrics-server \
    --version 2.11.1 \
    --namespace metrics

 

 

创建一个可读取Parameter Store中参数的service account

示例命令如下:

$ aws eks describe-cluster --name eksworkshop-eksctl --query cluster.identity.oidc.issuer --output text
$ eksctl utils associate-iam-oidc-provider --cluster eksworkshop-eksctl –approve
$ eksctl create iamserviceaccount --name spring-cloud --namespace default --cluster eksworkshop-eksctl --attach-policy-arn arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess --approve --override-existing-serviceaccounts

 

Spring Cloud项目的application.properties文件配置示例

Note: 在配置文件中,启用ip地址注册。

spring.application.name=hello-service

 

eureka.client.service-url.defaultZone=http://${eureka_server_1}:${eureka_server_port}/eureka,http://${eureka_server_2}:${eureka_server_port}/eureka,http://${eureka_server_3}:${eureka_server_port}/eureka
eureka.instance.prefer-ip-address=true

 

 

Docker镜像中的启动文件示例

在应用被打包成Docker镜像后,需要一个启动脚本,在镜像启动时初始化应用所需的环境。本示例中,通过启动文件,启动一个提供简单Hello world接口的Hello service。

此文件对应应用部署中Deployment yaml文件的args: [“/springCloud/env.sh”]启动脚本。

 

export eureka_server_port=$(aws ssm get-parameter --name='/Spring/Eureka/Server/port' --region us-east-2 | jq '.Parameter | .Value ' | sed 's/\"//g' )
export eureka_server_1=$(aws ssm get-parameter --name='/Spring/Eureka/Server/URL_1' --region us-east-2 | jq '.Parameter | .Value ' | sed 's/\"//g' )
export eureka_server_2=$(aws ssm get-parameter --name='/Spring/Eureka/Server/URL_2' --region us-east-2 | jq '.Parameter | .Value ' | sed 's/\"//g' )
export eureka_server_3=$(aws ssm get-parameter --name='/Spring/Eureka/Server/URL_3' --region us-east-2 | jq '.Parameter | .Value ' | sed 's/\"//g' )

java -jar /springCloud/app.jar

 

 

打包Docker镜像并推送至ECR

在创建好ECR的存储库后,可以在对应的存储库中查看打包Docker镜像及推送命令。

 

部署应用

 

通过Deployment,在EKS cluster上部署应用,其中镜像使用前述推送至ECR的镜像。示例文档如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: aws-hello
  labels:
    app: aws-hello
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: aws-hello
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: aws-hello
    spec:
      serviceAccountName: spring-cloud
      containers:
      - image: <ECR image path>
        imagePullPolicy: Always
        name: aws-hello
        resources:
          limits:
            cpu: "1"
          requests:
            cpu: "100m"
        command: ["/bin/sh","-c"]
        args: ["/springCloud/env.sh"]
        ports:
        - containerPort: 8080
          protocol: TCP

 

 

部署命令:

$ kubectl apply -f <deployment>.yaml

 

部署验证

 

查看Pod运行是否正常:

$ kubectl get pods

 

查看服务是否在Eureka中注册成功:

 

访问在API Gateway中对外开放的URL,查看服务是否正常:

 

应用的自动扩展

 

通过HPA (Horizontal Pod Autoscaler),进行Pod的自动伸缩:

$ kubectl autoscale deployment <aws-hello> --cpu-percent=50 --min=1 --max=10

 

查看HPA资源是否创建成功:

$ kubectl get hpa

 

使用busybox发送大量请求模拟高并发,并监控HPA:

$ kubectl get hpa -w

 

Pod在短时间内启动,应对并发流量:

 

新启动的服务模块正常注册到Eureka:

 

总结

Kubernetes是容器领域最流行的编排调度工具,它给大规模容器使用场景赋予了灵活而强大的调度能力。通过使用AWS托管的Kubernetes服务EKS,则能在享受Kubernetes强大能力的同时,减少运维Kubernetes群集的负担。选择把基于Spring Cloud框架开发的业务模块部署在EKS上,能使这些模块更快速,更灵活地响应突增的业务流量。结合部署于EC2的Eureka、API Gateway等Spring Cloud基础设施,整个微服务架构同时兼具了稳定性、可扩展性、快速响应等的特点,能更好地实现业务需求。

 

参考资料

[1] https://docs.thinkwithwp.com/zh_cn/eks/latest/userguide/what-is-eks.html

[2] https://www.eksworkshop.com/

[3] 翟永超.Spring Cloud 微服务实战[M].电子工业出版社:北京,2017:1.

 

本篇作者

何文安

AWS解决方案架构师,负责帮助客户进行上云架构的设计和咨询。在银行及电商行业有丰富的咨询和架构设计经验。加入 AWS 前曾于全球大型银行、国际消费品企业,担任系统分析师及领域专家,负责高并发、高可用系统架构设计,应用微服务化及云上迁移等具体实践。