我正在逐步学习如何使用现有的SSL通配符证书使用AWS EKS(用于Kubernetes的弹性容器服务)运行我的Spring Boot,mysql支持的应用程序的分步教程,但是找不到完整的解。
该应用程序是由MySQL数据库支持的标准Spring Boot自包含应用程序,运行在端口8080上。我需要以高可用性,高冗余度运行,包括需要处理大量写入和读取操作的MySQL db 。
我决定使用EKS托管集群,将自定义Docker映像保存到AWS拥有的ECR私有Docker存储库中,以对抗EKS托管的MySQL集群。并使用AWS颁发的SSL证书通过HTTPS进行通信。以下是我的解决方案,但我很想知道如何以不同的方式完成
答案 0 :(得分:4)
这是一个分步教程。在上一步完成之前,请不要继续前进。
创建EKS集群
按照the standard tutorial创建EKS集群。不要执行步骤4。完成后,您应该拥有一个正常工作的EKS集群,并且您必须能够使用kubectl
实用程序与该集群进行通信。从命令行执行时,您应该使用以下命令查看工作节点和其他集群元素
kubectl get all --all-namespaces
命令
安装MYSQL群集
我使用helm
按照this tutorial的步骤安装MySQL集群。这是步骤
安装头盔
由于我将Macbook Pro与homebrew
结合使用,因此我使用了brew install kubernetes-helm
命令
部署MySQL集群
请注意,在 MySQL集群和 Kubernetes(EKS)集群中,“集群”一词指的是两种不同的事物。基本上,您是将集群安装到集群中,就像俄罗斯的Matryoshka娃娃一样,因此您的MySQL集群最终将在EKS集群节点上运行。
我使用this tutorial的第二部分(忽略kops部分)来准备helm
图表并安装MySQL集群。引用头盔配置:
$ kubectl create serviceaccount -n kube-system tiller
serviceaccount "tiller" created
$ kubectl create clusterrolebinding tiller-crule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
clusterrolebinding.rbac.authorization.k8s.io "tiller-crule" created
$ helm init --service-account tiller --wait
$HELM_HOME has been configured at /home/presslabs/.helm.
Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
Happy Helming!
$ helm repo add presslabs https://presslabs.github.io/charts
"presslabs" has been added to your repositories
$ helm install presslabs/mysql-operator --name mysql-operator
NAME: mysql-operator
LAST DEPLOYED: Tue Aug 14 15:50:42 2018
NAMESPACE: default
STATUS: DEPLOYED
我完全按照上面的引用运行所有命令。
在创建集群之前,您需要一个包含ROOT_PASSWORD密钥的机密。
创建一个名为example-cluster-secret.yaml
的文件,并将以下YAML代码复制到其中
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
# root password is required to be specified
ROOT_PASSWORD: Zm9vYmFy
那ROOT_PASSWORD
是什么?原来,这是您计划与MySQL根用户一起使用的base64编码的密码。假设您想要root/foobar
(请不要实际使用foobar
)。编码密码最简单的方法是使用https://www.base64encode.org/这样的网站之一,该网站将foobar
编码为Zm9vYmFy
准备就绪后,执行kubectl apply -f example-cluster-secret.yaml
将创建一个新的秘密
然后,您需要创建一个名为example-cluster.yaml
的文件,并将以下YAML代码复制到其中:
apiVersion: mysql.presslabs.org/v1alpha1
kind: MysqlCluster
metadata:
name: my-cluster
spec:
replicas: 2
secretName: my-secret
请注意secretName
如何与您刚创建的秘密名称匹配。您可以将其更改为更有意义的名称,只要它在两个文件中都匹配即可。现在运行kubectl apply -f example-cluster.yaml
以最终创建一个MySQL集群。用
$ kubectl get mysql
NAME AGE
my-cluster 1m
请注意,我没有按照本文其余部分中所述配置备份。您无需执行该操作即可使数据库运行。但是如何访问您的数据库?此时,mysql服务已存在,但没有外部IP。就我而言,只要运行在同一EKS群集上的应用程序可以访问它,我什至不希望这样做。
但是,您可以使用kubectl
端口转发从运行kubectl
的dev框访问数据库。输入以下命令:kubectl port-forward services/my-cluster-mysql 8806:3306
。现在,您可以使用用户127.0.0.1:8806
和非编码密码(root
)从foobar
访问数据库。在单独的命令提示符下输入:mysql -u root -h 127.0.0.1 -P 8806 -p
。这样,您也可以使用MySQL Workbench来管理数据库,只是不要忘记运行port-forward
。当然,您可以将8806更改为您选择的其他端口
将应用程序打包为DOCKER图像和部署
要将您的Spring Boot应用程序部署到EKS集群中,您需要将其打包到一个Docker映像中并将其部署到Docker存储库中。让我们从Docker镜像开始。 like this one上有很多教程,但是步骤很简单:
将生成的自包含的Spring Boot jar文件放入目录中,并在相同目录中创建一个文本文件,其确切名称为Dockerfile
,并在其中添加以下内容:
FROM openjdk:8-jdk-alpine
MAINTAINER me@mydomain.com
LABEL name="My Awesome Docker Image"
# Add spring boot jar
VOLUME /tmp
ADD myapp-0.1.8.jar app.jar
EXPOSE 8080
# Database settings (maybe different in your app)
ENV RDS_USERNAME="my_user"
ENV RDS_PASSWORD="foobar"
# Other options
ENV JAVA_OPTS="-Dverknow.pypath=/"
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
现在只需在同一文件夹中运行Docker命令来创建映像。当然,这需要在您的开发箱中安装Docker客户端。
$ docker build -t myapp:0.1.8 --force-rm=true --no-cache=true .
如果一切顺利,您应该会看到docker ps
命令列出的图片
部署到私有ECR存储库
将新映像部署到ECR存储库很容易,并且ECR可以直接与EKS一起使用。登录到AWS控制台并导航到the ECR section。我觉得很困惑,显然每个图像需要一个存储库,但是当您单击“创建存储库”按钮时,将图像名称(例如myapp
)放入文本字段。现在,您需要复制图片的丑陋网址,然后返回命令提示符
标记并推送图像。我以一个伪造的URL为例:901237695701.dkr.ecr.us-west-2.amazonaws.com
,您需要复制上一步中的内容
$ docker tag myapp:0.1.8 901237695701.dkr.ecr.us-west-2.amazonaws.com/myapp:latest
$ docker push 901237695701.dkr.ecr.us-west-2.amazonaws.com/myapp:latest
此时,图像应显示在您创建的ECR存储库中
将您的应用程序部署到EKS集群
现在,您需要为应用程序的Docker映像创建Kubernetes部署。创建具有以下内容的myapp-deployment.yaml
文件
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: myapp-deployment
spec:
selector:
matchLabels:
app: myapp
replicas: 2
template:
metadata:
labels:
app: myapp
spec:
containers:
- image: 901237695701.dkr.ecr.us-west-2.amazonaws.com/myapp:latest
name: myapp
ports:
- containerPort: 8080
name: server
env:
# optional
- name: RDS_HOSTNAME
value: "10.100.98.196"
- name: RDS_PORT
value: "3306"
- name: RDS_DB_NAME
value: "mydb"
restartPolicy: Always
status: {}
请注意我如何为image
参数使用完整的URL。我还使用可以通过kubectl get svc my-cluster-mysql
命令获得的mysql集群的专用CLUSTER-IP。这对于您的应用程序(包括任何环境名称)将有所不同,但是您必须以某种方式向您的应用程序提供此信息。然后在您的应用中,您可以在application.properties
文件中设置类似的内容:
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://${RDS_HOSTNAME}:${RDS_PORT}/${RDS_DB_NAME}?autoReconnect=true&zeroDateTimeBehavior=convertToNull
spring.datasource.username=${RDS_USERNAME}
spring.datasource.password=${RDS_PASSWORD}
保存myapp-deployment.yaml
后,您需要运行此命令
kubectl apply -f myapp-deployment.yaml
这会将您的应用程序部署到EKS集群中。这将在集群中创建2个Pod,您可以使用kubectl get pods
命令
我们可以创建一个服务来放置应用程序pod,而不是尝试直接访问其中一个pod。使用以下内容创建一个myapp-service.yaml
:
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
ports:
- port: 443
targetPort: 8080
protocol: TCP
name: http
selector:
app: myapp
type: LoadBalancer
这就是魔术发生的地方!只需将端口设置为443并键入LoadBalancer
,系统就会创建一个Classic Load Balancer来放置您的应用程序。
顺便说一句,如果您不需要通过HTTPS运行您的应用程序,则可以将端口设置为80,这样就可以完成!
运行kubectl apply -f myapp-service.yaml
后,将在集群中创建服务,并且如果您转至AWS控制台EC2部分的“负载均衡器”部分,您将看到为您创建了一个新的均衡器。您还可以运行kubectl get svc myapp-service
命令,该命令将为您提供EXTERNAL-IP值,类似于bl3a3e072346011e98cac0a1468f945b-8158249.us-west-2.elb.amazonaws.com
。复制该内容,因为我们接下来需要使用它。
值得一提的是,如果您使用的是端口80,则只需将该URL粘贴到浏览器中即可显示您的应用
通过HTTPS访问您的应用
以下部分假定您具有AWS发行的SSL证书。如果不这样做,请转到AWS控制台“证书管理器”并为您的域创建通配符证书
在负载均衡器开始工作之前,您需要访问AWS console -> EC2 -> Load Balancers -> My new balancer -> Listeners
并单击SSL Certificate
列中的“更改”链接。然后在弹出窗口中,选择AWS颁发的SSL证书并保存。
转到AWS控制台的Route-53部分,然后为您的域选择一个托管区域,例如myapp.com.
。然后单击“创建记录集”并创建一个CNAME - Canonical name
设置为您想要的别名的Name
记录,例如从上方说cluster.myapp.com
和Value
设置为EXTERNAL-IP。在“保存记录集”之后,转到浏览器并输入https://cluster.myapp.com。您应该看到您的应用正在运行