Docker插件部署SpringBoot应用以及推送镜像到Docker Hub

环境准备

  • Maven
  • IDE
  • 服务器
  • Docker
  • 基本Docker 命令和Linux命令

Docker插件使用

Docker开启远程API

用vim编辑器修改docker.service文件

vi /usr/lib/systemd/system/docker.service
  • 修改文件内容
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
##修改后的内容
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock

让Docker支持http上传镜像

echo '{ "insecure-registries":["192.168.3.101:5000"] }' > /etc/docker/daemon.json
  • 修改配置后需要使用如下命令使配置生效

systemctl daemon-reload
  • 重新启动Docker服务

systemctl stop docker
systemctl start docker
  • 开启防火墙的Docker构建端口

firewall-cmd --zone=public --add-port=2375/tcp --permanent
firewall-cmd --reload

构建所有Docker镜像并上传

  • Maven使用Docker-maven-plugin插件
<properties>
    <docker.host>http://120.79.150.12:2375</docker.host>
</properties>
<!-- 打包 -->
   <build>
       <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>

           <plugin>
               <groupId>com.spotify</groupId>
               <artifactId>docker-maven-plugin</artifactId>
               <version>1.2.2</version>
               <executions>
                   <execution>
                       <id>build-image</id>
                       <phase>package</phase>
                       <goals>
                           <goal>build</goal>
                       </goals>
                   </execution>
               </executions>
               <configuration>
                   <imageName>eladmin/${project.artifactId}:${project.version}</imageName>
                   <dockerHost>${docker.host}</dockerHost>
                   <baseImage>java:8</baseImage>
                   <entryPoint>["java", "-jar", "-Dspring.profiles.active=prod","/${project.build.finalName}.jar"]
                   </entryPoint>
                   <resources>
                       <resource>
                           <targetPath>/</targetPath>
                           <directory>${project.build.directory}</directory>
                           <include>${project.build.finalName}.jar</include>
                       </resource>
                   </resources>
               </configuration>
           </plugin>
           <!--跳过单元测试-->
           <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-surefire-plugin</artifactId>
               <configuration>
                   <skipTests>true</skipTests>
               </configuration>
           </plugin>
       </plugins>
   </build>
  • 直接双击根项目jceadminpackage命令可以一次性打包所有应用的Docker镜像;

注意

  • 上述打包方式只适合内网环境部署应用
  • 接下来介绍如何使用docker插件部署应用到外网服务器中

使用Docker插件将服务部署到外网

分析原因

  • Docker为了实现集群管理,提供了远程管理的端口。Docker Daemon作为守护进程运行在后台,可以执行发送到管理端口上的Docker命令。
  • 当我们修改docker.service文件,修改启动命令,加入-H tcp://0.0.0.0:2375时,就会开放2375端口,且没有任何加密和认证过程,这种方式一般用在内网测试环境。如果你的服务器部署在公网上,任何知道你IP的人,都可以管理这台主机上的容器和镜像,想想就觉得可怕。

解决方案

开放远程管理端口后,没有做任何安全保护导致了这个问题。我们只要使用安全传输层协议(TLS)进行传输并使用CA认证即可

制作证书及秘钥

证书制作都在服务器上操作

  • 首先创建一个目录用于存储生成的证书和秘钥;
mkdir /mydata/docker-ca && cd /mydata/docker-ca
  • 制作CA机构证书
    • 创建CA证书私钥,期间需要输入两次用户名和密码,生成文件为ca-key.pem
openssl genrsa -aes256 -out ca-key.pem 4096
  • 根据私钥创建CA证书,期间需要输入上一步设置的私钥密码,生成文件为ca.pem
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -subj "/CN=*" -out ca.pem
  • 服务端证书
    • 创建服务端私钥,生成文件为server-key.pem
openssl genrsa -out server-key.pem 4096
  • 创建服务端证书签名请求文件,用于CA证书给服务端证书签名,生成文件server.csr
openssl req -subj "/CN=*" -sha256 -new -key server-key.pem -out server.csr
  • 创建CA证书签名好的服务端证书,期间需要输入CA证书私钥密码,生成文件为server-cert.pem
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem
  • 客户端证书

    • 创建客户端私钥,生成文件为key.pem
    openssl genrsa -out key.pem 4096
    • 创建客户端证书签名请求文件,用于CA证书给客户证书签名,生成文件client.csr
    openssl req -subj "/CN=client" -new -key key.pem -out client.csr
    • 为了让秘钥适合客户端认证,创建一个扩展配置文件extfile-client.cnf
    echo extendedKeyUsage = clientAuth > extfile-client.cnf
    • 创建CA证书签名好的客户端证书,期间需要输入CA证书私钥密码,生成文件为cert.pem
    openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile-client.cnf
    • 删除创建过程中多余的文件;
    rm -rf ca.srl server.csr client.csr extfile-client.cnf
    • 最终生成文件如下,有了它们我们就可以进行基于TLS的安全访问了。
-rw-r--r-- 1 root root 3326 May  6 19:11 ca-key.pem		CA证书私钥
-rw-r--r-- 1 root root 1765 May  6 19:11 ca.pem			CA证书		
-rw-r--r-- 1 root root 1696 May  6 19:13 cert.pem		客户端证书
-rw-r--r-- 1 root root 3247 May  6 19:13 key.pem		客户端证书私钥
-rw-r--r-- 1 root root 1647 May  6 19:12 server-cert.pem  	服务端证书
-rw-r--r-- 1 root root 3243 May  6 19:11 server-key.pem		服务端证书私钥

配置Docker支持TLS

  • 用vim编辑器修改docker.service文件;
vim /usr/lib/systemd/system/docker.service
  • 修改以ExecStart开头的配置,开启TLS认证,并配置好CA证书、服务端证书和服务端私钥,修改内容如下;
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --tlsverify --tlscacert=/mydata/docker-ca/ca.pem --tlscert=/mydata/docker-ca/server-cert.pem --tlskey=/mydata/docker-ca/server-key.pem
  • 重启Docker服务,这样我们的Docker服务就支持使用TLS进行远程访问了!
systemctl daemon-reload && systemctl restart docker

客户端访问

  • 直接使用docker-maven-plugin打包试试,由于我们的插件版本有点低,使用新一点版本的Docker会出现如下问题,升级到1.2.2版本解决该问题;
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.2</version>
  • 修改完版本后打包,发现TLS不再支持http了,需要改用https,修改<dockerHost>配置为https
<properties>
    <docker.host>https://120.79.150.12:2375</docker.host>
</properties>
  • 本地机器在指定目录添加客户端证书比如:D:\tools\docker-ca
ca.pem			CA证书		
cert.pem		客户端证书
key.pem		客户端证书私钥
  • 然后将该目录配置在插件的<dockerCertPath>节点下,最终插件配置如下;
<!-- 打包 -->
   <build>
       <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>

           <plugin>
               <groupId>com.spotify</groupId>
               <artifactId>docker-maven-plugin</artifactId>
               <version>1.2.2</version>
               <executions>
                   <execution>
                       <id>build-image</id>
                       <phase>package</phase>
                       <goals>
                           <goal>build</goal>
                       </goals>
                   </execution>
               </executions>
               <configuration>
                   <imageName>eladmin/${project.artifactId}:${project.version}</imageName>
                   <dockerHost>${docker.host}</dockerHost>
                   <baseImage>java:8</baseImage>
                   <entryPoint>["java", "-jar", "-Dspring.profiles.active=prod","/${project.build.finalName}.jar"]
                   </entryPoint>
                   <dockerCertPath>D:\tools\docker-ca</dockerCertPath>
                   <resources>
                       <resource>
                           <targetPath>/</targetPath>
                           <directory>${project.build.directory}</directory>
                           <include>${project.build.finalName}.jar</include>
                       </resource>
                   </resources>
               </configuration>
           </plugin>
           <!--跳过单元测试-->
           <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-surefire-plugin</artifactId>
               <configuration>
                   <skipTests>true</skipTests>
               </configuration>
           </plugin>
       </plugins>
   </build>
  • 执行命令mvn package,发现已经可以成功打包镜像,从此我们的2375端口终于可以安全使用了!
[root@iZwz9c743j35koyx2hety8Z docker-ca]# docker images
REPOSITORY                    TAG       IMAGE ID       CREATED         SIZE
jceadmin/jceadmin-system      2.6       583ebe19f084   5 hours ago     759MB

服务器中使用Docker推送镜像到Docker Hub

  • 登录Docker
docker login
# 输入用户名,密码
docker tag local-image:tagname new-repo:tagname
docker push new-repo:tagname
  • 对镜像打标签
docker tag eladmin/eladmin-system:2.6 sirniclolas/jceadmin-system:22.05
  • 推送到Docker Hub
docker push sirniclolas/jceadmin-system:22.05

参考文章


文章作者: rudy
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 rudy !
  目录