k8s中部署springboot项目
前情提要,如果对docker、harbor、k8s不熟悉的兄弟们,请先行阅读如下几篇文章:
- docker基础教程
- vm安装centos 7教程
- k8s集群搭建教程(特别注意,本篇文章基于此文章的集群环境搭建)
1、环境准备
注意:本地环境为windows+docker-desktop+idea
1.1、项目准备
1.1.1、下载项目
下载示例项目代码,地址:https://gitee.com/zhangjian2022/docker-demo.git,并导入IDEA集成开发工具。
1.1.2、项目仓库地址修改
修改maven项目配置文件pom.xml中docker插件dockerfile-maven-plugin的仓库地址及账号信息。配置文件如下:
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.13</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>harbor.jianjang.com:1443/jianjang/${project.build.finalName}</repository>
<tag>${project.version}</tag>
<username>zhangjian_sh</username>
<password>xxx123</password>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
1.1.3、打本地镜像
直接执行maven视图中的clean ,然后执行package即可,如下图
执行日志如下
[INFO]
[INFO] --- dockerfile-maven-plugin:1.4.13:build (default) @ docker-demo ---
[INFO] dockerfile: null
[INFO] contextDirectory: D:\workspace_home\docker-demo-master
[INFO] Building Docker context D:\workspace_home\docker-demo-master
[INFO] Path(dockerfile): null
[INFO] Path(contextDirectory): D:\workspace_home\docker-demo-master
[INFO]
[INFO] Image will be built as harbor.jianjang.com:1443/jianjang/docker-demo:1.0.1
[INFO]
[INFO] Step 1/10 : FROM java:8
[INFO]
[INFO] Pulling from library/java
[INFO] Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d
[INFO] Status: Image is up to date for java:8
[INFO] ---> d23bdf5b1b1b
[INFO] Step 2/10 : MAINTAINER JianJang
[INFO]
[INFO] ---> Running in aaaa7e8820e4
[INFO] Removing intermediate container aaaa7e8820e4
[INFO] ---> b5b2983e892e
[INFO] Step 3/10 : LABEL name="docker-demo" version="1.0.0" author="JianJang"
[INFO]
[INFO] ---> Running in 9394ec5a5beb
[INFO] Removing intermediate container 9394ec5a5beb
[INFO] ---> e5bdfc5d5d9b
[INFO] Step 4/10 : VOLUME /tmp
[INFO]
[INFO] ---> Running in cb93cb3fca43
[INFO] Removing intermediate container cb93cb3fca43
[INFO] ---> e8121f160657
[INFO] Step 5/10 : ARG JAR_FILE
[INFO]
[INFO] ---> Running in f8c092e9bcb8
[INFO] Removing intermediate container f8c092e9bcb8
[INFO] ---> 3cfeace4242a
[INFO] Step 6/10 : COPY ${JAR_FILE} /docker-demo.jar
[INFO]
[INFO] ---> ae044a6db18f
[INFO] Step 7/10 : ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/docker-demo.jar"]
[INFO]
[INFO] ---> Running in 68a6bec8ed31
[INFO] Removing intermediate container 68a6bec8ed31
[INFO] ---> 01f290515693
[INFO] Step 8/10 : ENV TZ=Asia/Shanghai
[INFO]
[INFO] ---> Running in f5c42a182a65
[INFO] Removing intermediate container f5c42a182a65
[INFO] ---> 44b9690b0628
[INFO] Step 9/10 : RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
[INFO]
[INFO] ---> Running in 65aa0b86615c
[INFO] Removing intermediate container 65aa0b86615c
[INFO] ---> 25100fc2542d
[INFO] Step 10/10 : EXPOSE 8081
[INFO]
[INFO] ---> Running in 97809bd8e68a
[INFO] Removing intermediate container 97809bd8e68a
[INFO] ---> 6ac157db0356
[INFO] Successfully built 6ac157db0356
[INFO] Successfully tagged harbor.jianjang.com:1443/jianjang/docker-demo:1.0.1
[INFO]
[INFO] Detected build of image with id 6ac157db0356
[INFO] Building jar: D:\workspace_home\docker-demo-master\target\docker-demo-docker-info.jar
[INFO] Successfully built harbor.jianjang.com:1443/jianjang/docker-demo:1.0.1
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:22 min
[INFO] Finished at: 2022-04-17T18:51:41+08:00
[INFO] ------------------------------------------------------------------------
我们看到日志中说明已经构建了镜像,并打了tag。如下图红框中部分,剩下的我们进行push即可
通过终端命令查看镜像信息,详细信息如下图
docker images
1.1.4、上传镜像到harbor
我们由上面的图可以看出镜像名称为harbor.jianjang.com:1443/jianjang/docker-demo,标签tag为1.0.1,然后我们使用命令docker push+reposity:tag命令进行上传,上传前需要登录私有仓库地址harbor.jianjang.com:1443,输入用户名及密码即可
docker login harbor.jianjang.com:1443
上传到镜像仓库
docker push harbor.jianjang.com:1443/jianjang/docker-demo:1.0.1
1.2、k8s配置harbor仓库
项目镜像:harbor.jianjang.com:1443/jianjang/docker-demo:1.0.1
1.2.1、镜像配置仓库地址
修改k8s集群中的docker配置文件/etc/docker/daemon.json。我的仓库地址为https://harbor.jianjang.com:1443,修改后如下:
{
"registry-mirrors": ["https://fhzep8jf.mirror.aliyuncs.com","https://docker.mirrors.ustc.edu.cn","https://harbor.jianjang.com:1443"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
1.2.2、重启docker服务
systemctl daemon-reload && systemctl restart docker
1.2.3、配置私有仓库登录秘钥
在k8s-master节点创建secret:k8s集群需要通过 docker-registry 类型的 secret 来设置拉取镜像的用户名和密码等登录信息。本文件中部署的Harbor私有镜像仓库的地址为harbor.jianjang.com:1443,登录名为 zhangjian_sh, 登录密码为 xxx123。创建命令如下:
kubectl create secret docker-registry my-ns-login \
--docker-server=harbor.jianjang.com:1443 \
--docker-username=zhangjian_sh \
--docker-password=xxx123 \
--namespace=my-namespace
查看登录凭证信息
kubectl get secrets
私有仓库登录凭证设置完毕,子节点会自动同步此配置故无需单独进行配置。
2、springboot服务部署
我们在自定义空间下部署我们的服务,并对外暴露服务,暴露端口为30002,然后验证service负载到不同pod节点情况。
服务 | 说明 | 备注 |
---|---|---|
pod | k8s最小单元 | |
Service | pod每次动态创建后,自动分配的ip会不同,所以引入了service(即服务的注册与发现) | |
namespace | 命名空间,主要用于隔离 |
2.1、创建namespace
此处我们通过kubernates-dashboard【https://192.168.2.2:30001/】来创建,当然也可以通过命令窗口创建。
2.1.1、编写namespace创建yaml脚本
apiVersion: v1 #类型为Namespace
kind: Namespace #类型为Namespace
metadata:
name: my-namespace #命名空间名称
labels:
name: label-test #pod标签
将上面创建拷贝粘贴到创建框中,然后点击【上传】按钮
创建成功后,点击空间列表页面,就可以看到创建名称为my-namespace的命名空间了,如下图
因为我们创建了新的命名空间,而我们之前创建secret没有指定命名空间,所以在新的空间下无法使用,必须重新创建secret,同样在k8s-master节点下创建接口,命令如下,增加指定命名空间my-namespace:
kubectl create secret docker-registry my-ns-login \
--docker-server=harbor.jianjang.com:1443 \
--docker-username=zhangjian_sh \
--docker-password=xxx123 \
--namespace=my-namespace
2.1.2、创建pod
使用我们的镜像,创建pod
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: my-namespace
name: springboot-deployment
spec:
selector:
matchLabels:
app: springboot
replicas: 2 #容器副本数量
template:
metadata:
labels:
app: springboot
spec:
imagePullSecrets:
- name: my-ns-login #拉取镜像凭证名称
containers:
- name: springboot #容器名称
image: harbor.jianjang.com:1443/jianjang/docker-demo:1.0.1 #镜像名称
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8081
将上面yaml脚本拷贝粘贴到pod创建窗口,然后点击【上传】按钮即可。
创建成功后界面
通过控制台查看命令pod启动情况,下面显示状态为容器创建中,因为镜像252M大小拉取镜像需要一段时间。
kubectl get pods -n my-namespace
等待一段时间后,我们再看一下,pod正常启动起来了
2.1.3、创建服务
我们这里创建service能够通过主机IP+端口的服务,所以我们创建NodePort类型服务
apiVersion: v1
kind: Service
metadata:
namespace: my-namespace
name: springboot
spec:
selector:
app: springboot
type: NodePort #类型为nodeport
ports:
- protocol: TCP
port: 8081
targetPort: 8081
nodePort: 30002 #暴露端口
在管控台选择Services服务菜单,然后选择my-namespace命名空间,然后点击右上角的【+】创建服务,将上面的脚本拷贝粘贴到编辑框中,然后点击【上传】按钮即可
查看服务情况
扩展:命令查看
kubectl get svc -n my-namespace
服务详情信息
以上springboot服务部署完毕。
2.2、服务负载均衡验证
根据上面服务部署过程,我们了解到两个pod的服务ip和端口及协议情况如下:
节点类型 | 运行节点名称 | ip | 端口 | 协议 | 备注 |
---|---|---|---|---|---|
pod | k8s-node1 | 10.122.36.69 | 8081 | TCP | 服务接口路径:/docker/hello |
pod | k8s-node2 | 10.122.169.136 | 8081 | TCP | 服务接口路径:/docker/hello |
NodePort | k8s-master | 10.10.43.110 | 8081 | TCP | 服务接口路径:/docker/hello,对上面连个节点进行负载 |
Service服务暴露 | k8s-master | 192.168.2.2 | 3002 | TCP | 服务接口路径:/docker/hello |
2.2.1、服务验证
通过curl 命令单个服务访问测试验证,接口返回当前pod节点的ip信息
curl 10.122.36.69:8081/docker/hello
curl 10.122.169.136:8081/docker/hello
返回内容如下
{
"code":"000000",
"data":{
"hostname":"springboot-deployment-6b44cdb4d7-2b6xx",
"localIp":"10.122.36.69"
},
"message":"交易成功"
}
{
"code":"000000",
"data":{
"hostname":"springboot-deployment-6b44cdb4d7-x7tng",
"localIp":"10.122.169.136"
},
"message":"交易成功"
}
通过NodePort服务IP验证负载均衡效果,命令如下,结果如下图
curl 10.10.43.110:3002/docker/hello
2.2.2、暴露服务验证
暴露的服务可以通过集群主机k8s-master节点+暴露端口进行负载均衡访问,我们postman中测试,结果如下图所示,经过测试,会进行请求分发,但是不是轮询模式。
至此,springboot服务在k8s中部署并验证完毕。