SpringBoot微服务使用docker容器化部署
还在手动部署SpringBoot应用?试试这个自动化插件!使用Maven插件为SpringBoot应用构建Docker镜像在成功使用 rancher 部署 k8s 之后,尝试将微服务也交由 rancher 管理安装私有镜像仓库由于需要推送到私有镜像仓库,于是使用 Docker 公司开发的私有镜像仓库 Registrydocker pull registry使用Docker容器运行Registry服
使用Maven插件为SpringBoot应用构建Docker镜像
在成功使用 rancher 部署 k8s 之后,尝试将微服务也交由 rancher 管理
安装私有镜像仓库
由于需要推送到私有镜像仓库,于是使用 Docker 公司开发的私有镜像仓库 Registry
docker pull registry
使用Docker容器运行Registry服务,需要添加环境变量REGISTRY_STORAGE_DELETE_ENABLED=true
开启删除镜像的功能
docker run -p 5000:5000 --name registry2 \
--restart=always \
-e REGISTRY_STORAGE_DELETE_ENABLED="true" \
-d registry:2
修改Docker Daemon的配置文件,文件位置为/etc/docker/daemon.json
,由于Docker默认使用HTTPS推送镜像,而我们的镜像仓库没有支持,所以需要添加如下配置,改为使用HTTP推送;
注:在每个节点的 daemon.json 文件都添加这个配置(因为你不清楚最终 rancher 把你的服务镜像部署到哪个节点上)
{
"insecure-registries": ["192.168.133.130:5000"]
}
重启 Docker 服务
systemctl daemon-reload && systemctl restart docker
镜像仓库可视化
由于私有镜像仓库管理比较麻烦,而docker-registry-ui
有专门的页面可以方便地管理镜像,所以我们安装它来管理私有镜像仓库。
下载docker-registry-ui
的Docker镜像
docker pull joxit/docker-registry-ui:static
使用Docker容器运行 docker-registry-ui
服务
docker run -p 8280:80 --name registry-ui \
--link registry2:registry2 \
-e REGISTRY_URL="http://registry2:5000" \
-e DELETE_IMAGES="true" \
-e REGISTRY_TITLE="Registry2" \
-d joxit/docker-registry-ui:static
我们先来试试私有镜像仓库是否可用,首先下载一个测试用的镜像busybox
docker pull busybox
给镜像busybox
打上私有仓库的标签,并设置版本为`v1.0``
docker tag busybox 192.168.3.101:5000/busybox:v1.0
之后推送到私有镜像仓库去
docker push 192.168.3.101:5000/busybox:v1.0
访问 docker-registry-ui
管理界面,即可查看到 busybox
镜像
将服务打包成docker镜像
fabric8io出品的
docker-maven-plugin
是一款集Docker镜像管理和容器管理于一身的插件,动动手指就可以把我们的SpringBoot应用部署到Docker容器中了,非常好用,下面来讲讲它的用法
要想使用 docker-maven-plugin
, 需要在 pom.xml
中添加该插件
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.33.0</version>
<configuration>
<!-- Docker 远程管理地址-->
<dockerHost>http://192.168.133.130:2375</dockerHost>
<!-- Docker 推送镜像仓库地址-->
<pushRegistry>http://192.168.133.130:5000</pushRegistry>
<images>
<image>
<!--由于推送到私有镜像仓库,镜像名需要添加仓库地址-->
<name>192.168.133.130:5000/demo/${project.name}:${project.version}</name>
<!--定义镜像构建行为-->
<build>
<!--定义基础镜像-->
<from>java:8</from>
<args>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</args>
<!--定义哪些文件拷贝到容器中-->
<assembly>
<!--定义拷贝到容器的目录-->
<targetDir>/</targetDir>
<!--只拷贝生成的jar包-->
<descriptorRef>artifact</descriptorRef>
</assembly>
<!--定义容器启动命令-->
<entryPoint>["java", "-jar","/${project.build.finalName}.jar"]</entryPoint>
<!--定义维护者-->
<maintainer>mike</maintainer>
</build>
</image>
</images>
</configuration>
</plugin>
我们构建镜像之前需要先将项目打包,然后再构建,否则会出错,直接使用如下命令即可;
mvn package docker:build
打包完成后就可以在我们的服务器上看到这个镜像了
注:其实还有挺多打包的方式的,具体可以参考文章开头的链接!
推送到镜像仓库
接下来我们使用 docker:push
命令即可把镜像推送到私有镜像仓库
mvn docker:push
通过 rancher 部署服务
从 docker registry ui
获取到该镜像的地址(把 ui 的端口改为仓库的端口5000)
docker pull 192.168.133.130:5000/demo/web-demo:0.0.1-SNAPSHOT
最终的配置
结果一
结果二
更新:2020-09-17
由于之前部署的服务只是简单的一个 Web 服务,输出 hello world。没有跟任何中间件关联,所以这次准备部署一个文件服务。
其实很多准备在上面已经说的非常清楚了,所以就不罗嗦了。这次依然是在 pom.xml
中加入 io.fabric8
的 docker 插件。
可是 mvn package
的过程碰到了问题,在单元测试的阶段抛出错误,简单粗暴的解决办法就是跳过这个阶段。
mvn clean package -Dmaven.test.skip=true docker:build
打包+部署成功
在 docker 的 images 里可以看到该镜像
运行
docker run -d --name platform-file -p 8773:8773 121
注:镜像id 开头 121
查看 file 容器输出日志
docker start 383 && docker logs -f 383
成功启动!!
访问接口
更新:2020-09-18
09-17 更新的那部分只是简单的将 file 服务打包成 docker 的镜像,并运行在 docker 里。无法满足快速扩容的需求!
由于有了昨天的铺垫,file 服务的镜像已经放在私库了,所以直接编辑相关部署的 yaml 文件就好了。
apiVersion: apps/v1
kind: Deployment #对象类型
metadata:
name: platform-file-test #名称
labels:
app: platform-file-test #标注
spec:
replicas: 1 #运行容器的副本数
selector:
matchLabels:
app: platform-file-test
template:
metadata:
labels:
app: platform-file-test
spec:
hostNetwork: true
containers: #docker容器的配置
- name: platform-file
image: 192.168.133.121:5000/demo/platform-file:1.3.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8773
部署节点的两种方式
nodePort部署
nodePort的部署思路就是通过在每个节点上开辟nodePort的端口,将流量引入进来,而后通过iptables首先转发到ingress-controller容器中(图中的nginx容器),而后由nginx根据ingress的规则进行判断,将其转发到对应的应用web容器中。
hostNetwork部署
以下解释来自网络:
解释1:相比较起来,hostNetwork模式不再需要创建一个nodePort的svc,而是直接在每个节点都创建一个ingress-controller的容器,而且将该容器的网络模式设为hostNetwork。也就是说每个节点物理机的80和443端口将会被ingress-controller中的nginx容器占用。当流量通过80/443端口进入时,将直接进入到nginx中。而后nginx根据ingress规则再将流量转发到对应的web应用容器中。
解释2:如果在POD中使用hostNetwork:true配置网络,pod中运行的应用程序可以直接看到宿主主机的网络接口,宿主主机所在的局域网上所有网络接口都可以访问到该应用程序。
在 spec 中添加 hostNetwork: true
,从而可以使用物理机网络
个人理解:就是将虚拟机的 ip 作为每个 Pod 的访问 ip(有待商榷)
结果
file 服务放在 default 空间下
[root@k8s-centos7-master-120 services]# kubectl get pods
NAME READY STATUS RESTARTS AGE
platform-file-test-78955b5544-7xxnz 1/1 Running 0 38m
查看日志
日志中关键信息
2020-09-18 07:24:54.324 [main][INFO ] com.alibaba.nacos.client.naming - [REGISTER-SERVICE] ybs_dev registering service DEFAULT_GROUP@@platform-file with instance: {"clusterName":"DEFAULT","enabled":true,"ephemeral":true,"healthy":true,"instanceHeartBeatInterval":5000,"instanceHeartBeatTimeOut":15000,"ip":"10.0.2.15","ipDeleteTimeout":30000,"metadata":{"preserved.register.source":"SPRING_CLOUD"},"port":8773,"weight":1.0}
从以上信息可知该服务的 ip 为 10.0.2.15
,端口为 8773
访问, 说明 file 服务成功部署到 k8s
[root@k8s-centos7-master-120 services]# curl http://192.168.133.121:8773/upload
{"code":-1,"message":"Request method 'GET' not supported","data":null,"count":null}
更多推荐
所有评论(0)