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

EKS为Spring Cloud部署带来的好处
EKS的特点
Amazon Elastic Kubernetes Service (Amazon EKS) 是一项完全托管的 Kubernetes 服务。由于EKS把安全性、可靠性和可扩展性作为产品最重要的特性进行实现,在公有云上使用Kubernetes技术的多数大型客户,都使用 EKS运行他们最敏感的任务关键型应用程序。
同时,EKS 与诸如 Amazon CloudWatch、Auto Scaling Group、Amazon Identity and Access Management (IAM) 和 Amazon Virtual Private Cloud (VPC) 之类的服务深度集成,为客户带来监控、扩展和负载平衡应用程序的无缝体验。
最后,EKS经认证与 Kubernetes 一致,因此客户可以利用社区中开源工具的所有优势。任何标准 Kubernetes 应用程序可轻松地迁移到 EKS,而无需重构代码。

EKS托管架构
📢 想学习 Amazon EKS 更多前沿实例?来2021亚马逊云科技中国峰会与业内领先的技术践行者们一起探讨交流吧!点击图片报名吧~
Amazon VPC CNI 插件
在Kubernetes的网络模型中,要求所有的网络插件实现必须满足如下要求:
1.所有的 Pod 可以与任何其他 Pod 直接通信,无需使用 NAT 映射(network address translation)
2.所有节点可以与所有 Pod 直接通信,无需使用 NAT 映射
3.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: 前置条件过程请参考Amazon 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$ eksctl create cluster -f < ClusterConfig >.yaml
创建一个可读取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.yaml
部署验证
查看Pod运行是否正常:
$ kubectl get pods

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

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

应用的自动扩展
通过HPA (Horizontal Pod Autoscaler),进行Pod的自动伸缩:
$ kubectl autoscale deployment--cpu-percent=50 --min=1 --max=10
查看HPA资源是否创建成功:
$ kubectl get hpa

使用busybox发送大量请求模拟高并发,并监控HPA:
$ kubectl get hpa -w
Pod在短时间内启动,应对并发流量:

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

总结
Kubernetes是容器领域最流行的编排调度工具,它给大规模容器使用场景赋予了灵活而强大的调度能力。通过使用亚马逊云科技托管的Kubernetes服务EKS,则能在享受Kubernetes强大能力的同时,减少运维Kubernetes群集的负担。选择把基于Spring Cloud框架开发的业务模块部署在EKS上,能使这些模块更快速,更灵活地响应突增的业务流量。结合部署于EC2的Eureka、API Gateway等Spring Cloud基础设施,整个微服务架构同时兼具了稳定性、可扩展性、快速响应等的特点,能更好地实现业务需求。
参考资料
[1] https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/what-is-eks.html
[2] https://www.eksworkshop.com/
[3] 翟永超.Spring Cloud 微服务实战[M].电子工业出版社:北京,2017:1.
本篇作者
何文安
亚马逊云科技解决方案架构师
负责帮助客户进行上云架构的设计和咨询。在银行及电商行业有丰富的咨询和架构设计经验。加入亚马逊云科技前曾于全球大型银行、国际消费品企业,担任系统分析师及领域专家,负责高并发、高可用系统架构设计,应用微服务化及云上迁移等具体实践。


听说,点完下面4个按钮
就不会碰到bug了!







