在kubernetes集群中部署SpringBoot应用和MySQL
环境准备:需要k8s集群和本地仓库,如果你还没有搭建,建议参考我上面两篇文章 Kubernetes集群搭建详细指南、 为kubernetes创建本地镜像仓库
环境准备
需要k8s集群和本地仓库,如果你还没有搭建,建议参考我上面两篇文章 Kubernetes集群搭建详细指南、 为kubernetes创建本地镜像仓库
部署MySQL
首先我们需要创建持久卷和持久卷声明,用来为MySQL挂载存储,不然容器重启数据就丢失了。
1)创建持久卷和持久卷声明
将以下的yaml声明保存为mysql-pv.yaml,然后执行apply命令。
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
kubectl apply -f mysql-pv.yaml
2)部署MySQL 5.6
这里选择了MySQL5.6的版本,你也可以换成其他的。
将以下的yaml声明保存为mysql-deployment.yaml,然后执行apply命令。
我们创建MySQL的同时创建了Service,Service为集群中的容器通信提供了服务发现功能。
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: mysql520
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
kubectl apply -f mysql-deployment.yaml
查看部署结果:
[root@k8s-master spring-boot-k8s-app]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-7446cc569d-nglnb 1/1 Running 4 40m
部署SpringBoot应用
1)在项目根目录创建Dockerfile
你的项目中要将spring-boot-k8s-app.jar
替换成自己的jar。
FROM openjdk:8-jdk
WORKDIR /opt/
COPY target/spring-boot-k8s-app.jar /opt/
EXPOSE 8080
CMD ["java","-Djava.security.egd=file:/dev/./urandom","-Xms400m","-Xmx400m","-jar","/opt/spring-boot-k8s-app.jar", "--spring.profiles.active=prod"]
2)记得修改配置文件中datasource
如下,其中url的第二个mysql
即为我们之前创建MySQL的service名称。MySQL的username
和password
则通过环境变量的形式读取,实际生产环境更推荐用Secret
来加密存储MySQL的用户名和密码。
spring:
datasource:
url: jdbc:mysql://mysql:3306/demo?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&autoReconnect=true
username: ${MYSQL_USERNAME}
password: ${MYSQL_PASSWORD}
initialization-mode: always
3)创建资源定义文件yaml
在项目根目录下创建deploy文件夹,按照如下创建spring-boot-deployment.yaml
文件,并放到deploy文件夹下。根据你的实际集群环境,你需要替换192.168.6.128:5000
为自己的镜像仓库。
kind: Service
apiVersion: v1
metadata:
name: spring-boot-k8s-app-service
spec:
type: NodePort
selector:
app: spring-boot-k8s-app
ports:
- protocol: TCP
port: 8080
nodePort: 32082
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-boot-k8s-app-deployment
spec:
replicas: 1
selector:
matchLabels:
app: spring-boot-k8s-app
template:
metadata:
labels:
app: spring-boot-k8s-app
spec:
containers:
- name: spring-boot-k8s-app-controller
image: 192.168.6.128:5000/spring-boot-k8s-app:20200907-011935
ports:
- containerPort: 8080
env:
- name: MYSQL_PORT
value: '3306'
- name: MYSQL_USERNAME
value: root
- name: MYSQL_PASSWORD
value: mysql520
4)一把梭命令脚本
为了免去手工部署敲命令的烦恼,直接一把梭将命令整合成如下的bash脚本,命名为auto-deploy.sh
,并扔进deploy文件夹下。这个脚本就实现了这么几件事:
- 从git拉取最新代码
- maven打包
- 打docker镜像
- 推送镜像到本地仓库
- 更新Deployment资源模板文件的镜像tag
- 按照更新后的文件进行部署
git pull origin master
mvn clean package -DskipTests
tag=$(date +"%Y%m%d-%H%M%S")
if [ $# -eq 1 ]; then
tag=$1
fi
image=192.168.6.128:5000/spring-boot-k8s-app:$tag
imagename=spring-boot-k8s-app:$tag
docker build -t $image .
docker push $image
echo "$image"
echo "$imagename"
pwd
cp deploy/spring-boot-deployment.yaml deploy/spring-boot-deployment-tmp.yaml
sed -i s#spring-boot-k8s-app:[0-9]*-[0-9]*#$imagename# deploy/spring-boot-deployment-tmp.yaml
kubectl apply -f deploy/spring-boot-deployment-tmp.yaml
注意:此auto-deploy.sh中,根据你的实际集群环境,你需要替换192.168.6.128:5000
为自己的镜像仓库。
5)通过脚本完成部署
sh deploy/auto-deploy.sh
查看部署效果,发现mysql调度到node1节点,spring boot 应用调度到node2节点:
[root@k8s-master spring-boot-k8s-app]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql-7446cc569d-nglnb 1/1 Running 4 138m 10.244.1.38 k8s-node1 <none> <none>
spring-boot-k8s-app-deployment-587b6dc8c8-bx792 1/1 Running 0 5m48s 10.244.2.29 k8s-node2 <none> <none>
查看各node的ip:
[root@k8s-master spring-boot-k8s-app]# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-master Ready master 2d v1.19.0 192.168.6.128 <none> CentOS Linux 7 (Core) 3.10.0-957.12.2.el7.x86_64 docker://18.6.1
k8s-node1 Ready <none> 2d v1.19.0 192.168.6.131 <none> CentOS Linux 7 (Core) 3.10.0-957.12.2.el7.x86_64 docker://18.6.1
k8s-node2 Ready <none> 2d v1.19.0 192.168.6.132 <none> CentOS Linux 7 (Core) 3.10.0-957.12.2.el7.x86_64 docker://18.6.1
由于当前springboot项目对应的Service为NodePort类型,那么它可以从集群外部通过任意的NodeIp:NodePort
进行访问。直接通过宿主机浏览器访问http://192.168.6.128(131/132):32082/
地址即可看到效果。
项目源码已上传到GitHub spring-boot-k8s-app,且已使用Secret来代替明文环境变量。按照README上简单几行命令即可将应用跑起来,有兴趣可以了解下。
更多推荐
所有评论(0)