在Minikube中使用Kubernetes来部署Spring boot项目连接数据库Mysql

描述

本文章主要记录如何在Minikube单个Node中使用Kubernetes来部署一个API REST项目并且该程序连接数据库Mysql。我所使用的系统是Windows 10。
在这个实验中,我最开始使用的是docker作为driver,但是在windows系统上,最后需要使用ingress获得允许外部连接IP时,这个IP没有用。经过多方面的查找,我并没有找到解决的办法,然而同样的操作命令在Linux中,IP使用没有任何问题。所以, 之后我使用了virtualbox,其他命令不变,ingress验证可以用。

1.Docker

首先开始第一步,建立Spring Boot项目的Docker 镜像。
以下内容为Dockerfile文件。

FROM adoptopenjdk/openjdk15-openj9:alpine-jre  #使用轻量级linux的镜像,里面使用JDK15
RUN mkdir /app        #在容器的根目录中 创建一个叫app的文件夹
COPY ./t2.jar /app    #把当前所在路径中的t2.jar文件复制到容器的app的文件夹里面
WORKDIR /app          #把容器的工作目录换成app,所以运行docker exec -it 容器名 /bin/bash 进入容器的时候,所在位置是app
EXPOSE 8081           #暴露端口 8081
ENTRYPOINT ["java", "-jar", "/app/t2.jar"]   #初始化运行容器时,运行程序

创建Docker镜像
-t name, name就是之后该镜像的名字。

docker build . -t image-t2
docker images #列出镜像,确定是否创建成功

如果要上传到某个远程仓库中可以运行以下命令。在这里仓库网址是example.com

docker image tag image-t2 example.com:5000/image-t2
docker image push example.com:5000/image-t2

在这个实验的过程中,我如果使用VirtualBox作为Minikube的driver,windows 系统不能同时运行Docker和Minikube,总有一个会报Virtualization(虚拟化的错误), 因此在使用中必须要把docker镜像上传到远程仓库中。如果Minikube使用Docker作为driver,可以加载本地镜像,不用上传到远程仓库也可以使用。

2.Minikube

首先,运行Minikube。Minikube会在本地创建一个只有一个节点的Kubernetes的Cluster。

minikube start --driver=virtualbox  #运行软件, 如果默认内存大小不够,可以使用这些参数来进行修改 --cpus=4 --memory=6000
minikube addons enable dashboard #激活后台控制版面
minikube addons enable ingress #激活Ingress, 允许cluster外部可以访问内容服务。 
minikube dashboard #打开kubernetes控制版面

然后开始应用部署文件。

  1. 将数据库密码存在Secret中。创建一个yaml文件命名为secret.yaml,该文件包括以下内容
apiVersion: v1
kind: Secret
metadata:
 name: mysql-secret
data:
 username: bXlzcWw= #mysql 使用的是base64的编码
password: bXlzcWw=

部署文件:

kubectl apply -f secret.yaml
  1. PersistentVolumen,用于储存数据库内容。 persistenVolumne.yaml的文件内容如下:
apiVersion: v1
kind: PersistentVolume
metadata:
 name: mysql-pv
spec:
 storageClassName: example.file   #自定义文件名
 accessModes:
 - ReadWriteOnce
 capacity:
 storage: 1Gi
 hostPath:
 path: /data/mysql-pv   #自定义路径 

部署文件:

kubectl apply -f persistentVolume.yaml
  1. StatefulSet,创建数据库服务接口。 statefulSet.yaml的文件内容如下:
apiVersion: apps/v1
kind: StatefulSet
metadata:
 name: mysql-statefulset
spec:
 replicas: 1
 selector:
 matchLabels:
 app: mysql
 serviceName: "mysql-service"
 template:
 metadata:
 labels:
 app: mysql 
 spec:
 containers:
 - name: mysql
 image: mysql:latest
 ports:
 - containerPort: 3306
 name: mysql-port
 env:
 - name: MYSQL_ROOT_PASSWORD
 valueFrom:
 secretKeyRef:
 name: mysql-secret
 key: password
 - name: MYSQL_DATABASE
 value: example
 - name: MYSQL_USER
 valueFrom:
 secretKeyRef:
 name: mysql-secret
 key: username
 - name: MYSQL_PASSWORD
 valueFrom:
 secretKeyRef:
 name: mysql-secret
 key: password
 volumeMounts:
 - name: mysql-pvc
 mountPath: /var/lib/mysql
 volumeClaimTemplates:
 - metadata:
 name: mysql-pvc
 spec:
 storageClassName: example.file
 accessModes: [ "ReadWriteOnce" ]
 resources:
 requests:
 storage: 1Gi

部署文件:

kubectl apply -f statefulSet.yaml

如果要在数据库中初始化表和数据, 可以通过以下命令进入到容器里。

kubectl cp ./data.sql 容器名字:data.sql #将本地文件复制到容器里

kubectl exec -it 容器名字 /bin/bash # 进入到容器中
mysql -u mysql -p # 进入之后,这个命名可以进入到mysql应用里 之后就可以对数据进行操作
  1. ConfigMap,用来定义一些Spring boot项目中的设置变量。 configMap.yaml的文件内容为:
apiVersion: v1
kind: ConfigMap
metadata:
 name: configmap
 namespace: default
data:
 MYSQL_URL: "jdbc:mysql://mysql-service:3306/twcam?serverTimezone=UTC"

部署文件:

kubectl apply -f configMap.yaml
  1. Deployment,部署应用容器。 部署完毕之后会自动创建Pod和一个Repliset。这里镜像将从仓库example中拉取,并且拉取不需要密码。 如果没有仓库,可以使用minikube load image-name 通过本地加载镜像到minikube中, 在填写image的参数时,直接写镜像名字即可。
    deployment.yaml的文件内容为:
apiVersion: apps/v1
kind: Deployment
metadata:
 name: t2-deployment
spec:
 selector:
 matchLabels:
 app: t2
 replicas: 1
 template:
 metadata:
 labels:
 app: t2
 spec:
 containers:
 - env:
 - name: SPRING_DATASOURCE_URL #在spring boot项目中, 该变量名字为datasource_url
 valueFrom:
 configMapKeyRef:
 name: configmap
 key: MYSQL_URL
 name: t2
 image:  example.com:5000/image-t2
 imagePullPolicy: IfNotPresent
 ports:
 - containerPort: 8081

部署文件:

kubectl apply -f deployment.yaml
  1. Service,将应用暴露在节点中。service.yaml的文件内容为:
apiVersion: v1
kind: Service
metadata:
 name: t2-service
 labels:
 app: t2
spec:
 type: NodePort
 selector:
 app: t2
 ports:
 - protocol: TCP
 port: 8081

部署文件:

kubectl apply -f service.yaml
  1. Ingress,允许外部访问cluster中的服务。Ingress文件内容为:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: ingress
 annotations:
 nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
 rules:
 - http:
 paths:
 - path: /t2/(.*)
 pathType: Prefix
 backend:
 service:
 name: t2-service
 port:
 number: 8081

部署文件:

kubectl delete -A ValidatingWebhookConfiguration ingress-nginx-admission # 如果在apply中报错,运行该命令
kubectl apply -f ingress.yaml

结束之后,可以通过以下命令来获得IP和端口来对应用进行访问。

Kubectl get ingress  #IP
kubectl get service -n ingress-nginx ingress-nginx-controller #端口

访问链接为:

http://IP:端口/t2
posted @ 2021-09-23 18:09  学不可以己  阅读(611)  评论(0)    收藏  举报