【CI/CD技术专题】「Docker实战系列」(1)本地进行生成镜像以及标签Tag推送到DockerHub

简介: 【CI/CD技术专题】「Docker实战系列」(1)本地进行生成镜像以及标签Tag推送到DockerHub

背景介绍


Docker镜像构建成功后,只要有docker环境就可以使用,但必须将镜像推送到Docker Hub上去。创建的镜像最好要符合Docker Hub的tag要求,因为在Docker Hub注册的用户名是liboware,最后利用docker push命令推送镜像到公共仓库。



前提概要


你需要在Docker hub注册用户:到官网注册账号:hub.docker.com/

例如:注册账号名称:liboware

image.png



在本地服务器登录docker:


例如在CentOS7服务器

[root@localhost ~]#  docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: liboware   ##输入账号
Password:          ##输入密码
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
复制代码



查看镜像

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nacos               v1         9e5f6711d527        3 days ago          178MB
mysql               v1                  9e5f6711d527        3 days ago          178MB
复制代码


docker tag建立镜像

[root@localhost ~]# docker tag nacos:v1 liboware/nacos:v1
复制代码


docker images 查看镜像

[root@localhost ~]# docker images 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nacos               v1         9e5f6711d527        3 days ago          178MB
nginx               v1                  9e5f6711d527        3 days ago          178MB
liboware/mysql     v1                  9e5f6711d527        3 days ago          178MB
[root@localhost ~]# 
复制代码


docker hub推送镜像

docker push  注册docker用户名/REPOSITORY:TAG

[root@localhost ~]# docker push liboware/nacos:v1
The push refers to repository [docker.io/llxxyy/nginx-io]
833a0f6a6ff9: Pushed 
10bfe402500e: Pushed 
d43641d7d594: Mounted from library/nginx 
c2adabaecedb: Mounted from library/nginx 
v1: digest: sha256:67dcdae5578c0374019cc899731543cfd7c48fe5780e84233a258f2bf7d2ceda size: 1155
[root@localhost ~]# 
复制代码


注:推送Docker Hub速度很慢,耐心等待,很有可能失败,失败会尝试多次重传,之后断开推送(但已推送上去的会保留,保留时间不知道是多久)。


hub docker效果


image.png


Docker 使用发布的镜像


docker@default:~$ docker search liboware/nacos
NAME                               DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED  
liboware/nacos   In this  image server you can use ma...   0 
复制代码


在pull下来

[root@localhost ~]# docker pull liboware/nacos:v1
v1: Pulling from liboware/nacos
Digest: sha256:67dcdae5578c0374019cc899731543cfd7c48fe5780e84233a258f2bf7d2ceda
Status: Downloaded newer image for liboware/nacos:v1
docker.io/liboware/nacos:v2
复制代码


确认pull成功

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               stable-perl         9e5f6711d527        3 days ago          178MB
nginx               v1                  9e5f6711d527        3 days ago          178MB
libo/nacos     v1                  9e5f6711d527        3 days ago          178MB
复制代码


遇到的问题


  1. 执行:docker push nacos:v1【提示denied: requested access to the resource is denied】
  2. 我们可以列出所有镜像:docker images
  3. 建立tag将要发布的镜像改到自己账户名下,我的账户名:liboware
docker tag nacos:v2  liboware/nacos:v2
复制代码


  1. 再次推送:docker push  liboware/nacos:v2【成功】




使用Maven插件构建Docker镜像的方法


本文介绍了使用Maven插件构建Docker镜像的方法,分享给大家,具体如下:



工具

工欲善其事,必先利其器。笔者经过调研,有以下几款Docker的Maven插件进入笔者视野。



插件名称+官方地址




修改宿主机配置(docker可以远程访问)


  • 修改宿主机的docker配置,让其支持远程访问。
vi /usr/lib/systemd/system/docker.service
复制代码


开启docker远程API,修改docker配置文件 docker.service进入编辑模式后。



ExecStart=后添加配置-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock

保存后退出,重新加载配置文件#systemctl daemon-reload   ,启动docker #systemctl start docker 。



  • 刷新配置,重新服务
systemctl daemon-reload
systemctl restart docker
复制代码




配置 DOCKER_HOST


docker-maven-plugin 插件默认连接本地 Docker 地址为:localhost:2375,所以我们需要先设置下环境变量。


DOCKER_HOST=tcp://<host>:2375
复制代码

注意:如果没有设置 DOCKER_HOST 环境变量,可以命令行显示指定 DOCKER_HOST 来执行,如我本机指定 DOCKER_HOST:DOCKER_HOST=tcp://:2375




例如


  • ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock  ,这里就写4个0,你可别改成自己的ip哦,
  • 输入#netstat -anp|grep 2375 显示docker正在监听2375端口,输入#curl 127.0.0.1:2375/info  显示一大堆信息,证明远程api就弄好了
  • 在windows系统环境变量中新建DOCKER_HOST,值为tcp://10.100.74.220:2375,(你改成你自己的docker服务器ip地址)

image.png




使用插件构建Docker镜像


在我们持续集成过程中,项目工程一般使用 Maven 编译打包,然后生成镜像,通过镜像上线,能够大大提供上线效率,同时能够快速动态扩容,快速回滚,着实很方便。docker-maven-plugin 插件就是为了帮助我们在Maven工程中,通过简单的配置,自动生成镜像并推送到仓库中



添加插件


在pom.xml中添加下面这段:

<build>
   添加相关的镜像插件
 </build>
复制代码



构建镜像


构建镜像可以使用一下两种方式,第一种是将构建信息指定到 POM 中,第二种是使用已存在的 Dockerfile 构建。(支持将 FROM, ENTRYPOINT, CMD, MAINTAINER 以及 ADD 信息配置在 POM 中,不需要使用 Dockerfile 配置。)


  • 第一种方式,支持将 FROM, ENTRYPOINT, CMD, MAINTAINER 以及 ADD 信息配置在 POM 中,不需要使用 Dockerfile 配置


  • 第二种方式,如果使用 VOLUME 或其他 Dockerfile 中的命令的时候,需要创建一个 Dockerfile,并在 POM 中配置 dockerDirectory 来指定路径即可。(创建一个 Dockerfile,并在 POM 中配置 dockerDirectory 来指定路径即可)



添加docker-maven-plugin
<plugin>
  <groupId>com.spotify</groupId>
  <artifactId>docker-maven-plugin</artifactId>
  <version>0.4.13</version>
  <configuration>
   <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>  
    <imageName>{dockerhub名称/imageName}</imageName> 
   <imageTags>
         <imageTag>{imageTag}</imageTag>
     </imageTags>
    <baseImage>{baseImage}</baseImage>
    <entryPoint>{end[point]}</entryPoint>
  <maintainer>author author@email.com</maintainer>
     <workdir>/ROOT</workdir>
    <resources>
      <resource>
        <targetPath>/</targetPath> 
        <directory>${project.build.directory}</directory>
        <include>${project.build.finalName}.jar</include> 
      </resource>
    </resources>
  </configuration>
</plugin>
复制代码


  • {dockerhub名称/imageName}:


  • dockerhub名称:对应DockerHub用户名,,一定要是符合正则[a-z0-9-_.]的,否则构建不会成功
  • imageName:对应 DockerHub 仓库名,一定要是符合正则[a-z0-9-_.]的,否则构建不会成功
  • 可以直接指定:project.groupId/{project.groupId}/project.groupId/{project.artifactId}



  • {imageTag}:镜像标签,相当于标签或者版本,latest。


  • {baseImage}: 指定基础镜像,等同 FROM 指令,例如:java,当然可以不用,直接在dockerfile文件中生成。
  • {endpoint}:// 等同于 ENTRYPOINT 指令,例如: ["java","-jar","app.jar"]

这里是复制 jar 包到 docker 容器指定目录配置,也可以写到 Dockerfile中

  • {project.build.directory}:指定要复制的根目录,${project.build.directory} 表示 target 目录。
  • {project.build.finalName}:指定要复制的文件,${project.build.finalName}.jar 指打包后的 jar 文件。
  • resources.resource.targetPath:将打包后的资源文件复制到该目录;
  • resources.resource.directory:需要复制的文件所在目录,maven打包的应用jar包保存在target目录下面;
  • resources.resource.include:需要复制的文件,打包好的应用jar包。


读取 Dockerfile 文件就不必指定 baseImage 和 entrypoint


  • 指定要读取的Dockerfile文件:
<dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
复制代码




创建Dockerfile


\src\main\docker

image.png


内容如下


FROM java:8
VOLUME /tmp
ADD admin-service-80-0.0.1-SNAPSHOT.jar admin-service-80.jar
RUN bash -c 'touch /admin-service-80.jar'
EXPOSE 80
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","${project.build.finalName}.jar"]
复制代码
执行以下命令构建 Docker 镜像

mvn clean package docker:build

[INFO] --- docker-maven-plugin:1.0.0:build (default-cli) @ mavenDemo ---
[INFO] Building image mavendemo
Step 1/5 : FROM java
 ---> d23bdf5b1b1b
Step 2/5 : MAINTAINER docker_maven docker_maven@email.com
 ---> Using cache
 ---> 2faf180d4a50
Step 3/5 : WORKDIR /ROOT
 ---> Using cache
 ---> 862210f7956a
Step 4/5 : ENTRYPOINT java -jar mavenDemo.jar
 ---> Running in 96bbe83de6ec
 ---> c29009c88993
Removing intermediate container 96bbe83de6ec
Step 5/5 : CMD java -version
 ---> Running in f69b8d2a75b1
 ---> bc8d54014325
Removing intermediate container f69b8d2a75b1
Successfully built bc8d54014325
复制代码

image.png

执行 docker images 查看刚才构建的镜像



执行命令


  • mvn clean package docker:build:只执行 build 操作
  • mvn clean package docker:build -DpushImage 执行 build 完成后 push 镜像
  • mvn clean package docker:build -DpushImageTag 执行 build 并 push 指定 tag 的镜像


注意:这里必须指定至少一个 imageTag,它可以配置到POM 中,也可以在命令行指定



命令行指定如下:


mvn clean package docker:build -DpushImageTags -DdockerImageTags=imageTag_1 -DdockerImageTags=imageTag_2,POM 文件中指定配置如下:

<build>
  <plugins>
    ...
    <plugin>
      <configuration>
        ...
        <imageTags>
           <imageTag>imageTag_1</imageTag>
           <imageTag>imageTag_2</imageTag>
        </imageTags>
      </configuration>
    </plugin>
    ...
  </plugins>
</build>
复制代码




绑定Docker 命令到 Maven 各个阶段


  • 可以绑定 Docker 命令到 Maven 各个阶段,我们可以把 Docker 分为 build、tag、push,然后分别绑定 Maven 的 package、deploy 阶段。
  • 只需要执行mvn deploy就可以完成整个 build、tag、push操作了,当我们执行mvn build就只完成 build、tag 操作
  • 除此此外,当我们想跳过某些步骤或者只执行某个步骤时,不需要修改 POM 文件,只需要指定跳过 docker 某个步骤即可。比如当我们工程已经配置好了自动化模板了,但是这次我们只需要打镜像到本地自测。


  • 不想执行 push 阶段,那么此时执行要指定参数-DskipDockerPush就可跳过 push 操作了。


以上示例,当我们执行mvn package时,执行 build、tag 操作,当执行mvn deploy时,执行build、tag、push 操作。如果我们想跳过 docker 某个过程时,只需要:


  • -DskipDockerBuild 跳过 build 镜像
  • -DskipDockerTag 跳过 tag 镜像
  • -DskipDockerPush 跳过 push 镜像
  • -DskipDocker 跳过整个阶段



例如:我们想执行 package 时,跳过 tag 过程,那么就需要mvn package -DskipDockerTag。

<build>
    <plugins>
        <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>1.0.0</version>
            <configuration>
                <imageName>mavendemo</imageName>
                <baseImage>java</baseImage>
                <maintainer>docker_maven docker_maven@email.com</maintainer>
                <workdir>/ROOT</workdir>
                <cmd>["java", "-version"]</cmd>
                <entryPoint>["java", "-jar", "${project.build.finalName}.jar"]</entryPoint>
                <resources>
                    <resource>
                        <targetPath>/ROOT</targetPath>
                        <directory>${project.build.directory}</directory>
                        <include>${project.build.finalName}.jar</include>
                    </resource>
                </resources>
            </configuration>
            <executions>
                <execution>
                    <id>build-image</id>
                    <phase>package</phase>
                    <goals>
                        <goal>build</goal>
                    </goals>
                </execution>
                <execution>
                    <id>tag-image</id>
                    <phase>package</phase>
                    <goals>
                        <goal>tag</goal>
                    </goals>
                    <configuration>
                        <image>mavendemo:latest</image>
                        <newName>docker.io/wanyang3/mavendemo:${project.version}</newName>
                    </configuration>
                </execution>
                <execution>
                    <id>push-image</id>
                    <phase>deploy</phase>
                    <goals>
                        <goal>push</goal>
                    </goals>
                    <configuration>
                        <imageName>docker.io/wanyang3/mavendemo:${project.version}</imageName>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
复制代码

docker-maven-plugin 插件还提供了很多很实用的配置,稍微列举几个参数吧。

image.png


安全认证配置


当我们 push 镜像到 Docker 仓库中时,不管是共有还是私有,经常会需要安全认证,登录完成之后才可以进行操作。当然,我们可以通过命令行 docker login -u user_name -p password docker_registry_host 登录,但是对于自动化流程来说,就不是很方便了。使用 docker-maven-plugin 插件我们可以很容易实现安全认证


首先在 Maven 的配置文件 setting.xml 中增加相关 server 配置,主要配置 Docker registry用户认证信息


<servers>
  <server>
    <id>my-docker-registry</id>
    <username>wanyang3</username>
    <password>12345678</password>
    <configuration>
      <email>wanyang3@mail.com</email>
    </configuration>
  </server>
</servers>
复制代码

然后只需要在 pom.xml 中使用 server id 即可。

<plugin>
  <plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>1.0.0</version>
    <configuration>
      <imageName>registry.example.com/wanyang3/mavendemo:v1.0.0</imageName>
      ...
      <serverId>my-docker-registry</serverId>
    </configuration>
  </plugin>
复制代码



使用私有Docker仓库地址


实际工作环境中,我们需要 push 镜像到我们私有 Docker 仓库中,使用d ocker-maven-plugin 插件我们也是很容易实现,有几种方式实现



修改 POM 文件 imageName 操作

<configuration>
    <imageName>{privateImageHubUrl}/imageName/tag</imageName>
    ...
</configuration>
复制代码


以以上的格式进行输出即可。



修改 POM 文件中 newName 操作

<configuration>
    <imageName>mavendemo</imageName>
    ...
</configuration>
<execution>
    <id>tag-image</id>
    <phase>package</phase>
    <goals>
        <goal>tag</goal>
    </goals>
    <configuration>
        <image>mavendemo</image>
        <newName>{privateImageHubUrl}/imageName/tag</newName>
    </configuration>
</execution>
复制代码


重新启动Docker服务

systemctl stop docker
systemctl start docker
复制代码



开启防火墙的Docker构建端口

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




相关文章
|
1天前
|
测试技术 持续交付 Docker
Docker in Docker原理与实战
Docker in Docker原理与实战
4 0
|
2天前
|
存储 安全 持续交付
【Docker 专栏】Docker 镜像的版本控制与管理
【5月更文挑战第9天】本文探讨了Docker镜像版本控制与管理的重要性,包括可重复性、回滚能力、协作开发和持续集成。常用方法有标签、构建参数和版本控制系统。管理策略涉及定期清理、分层管理和镜像仓库。语义化标签、环境变量和配置文件在版本控制中有应用。版本系统与Docker结合能跟踪历史和促进协作。注意点包括优化镜像大小、确保安全性和兼容性。案例分析和未来趋势展示了持续发展的镜像管理技术,为Docker应用的稳定与进步保驾护航。
【Docker 专栏】Docker 镜像的版本控制与管理
|
2天前
|
运维 安全 Docker
【Docker 专栏】Docker 镜像安全扫描与漏洞修复
【5月更文挑战第9天】Docker技术在软件开发和部署中带来便利,但其镜像安全问题不容忽视。本文探讨了Docker镜像安全扫描与漏洞修复,强调了镜像安全对应用和系统的重要性。文中介绍了静态和动态扫描方法,列举了软件漏洞、配置漏洞和恶意软件等常见安全问题,并提到了Clair和Trivy等扫描工具。修复策略包括更新软件、调整配置和重建镜像。此外,加强安全意识、规范镜像制作流程和定期扫描是管理建议。未来,将持续面对新的安全挑战,需持续研究和完善安全技术。
【Docker 专栏】Docker 镜像安全扫描与漏洞修复
|
2天前
|
Java Linux 数据安全/隐私保护
Docker自定义JDK镜像并拉取至阿里云镜像仓库全攻略
Docker自定义JDK镜像并拉取至阿里云镜像仓库全攻略
|
2天前
|
存储 弹性计算 运维
Docker数据集与自定义镜像:构建高效容器的关键要素
Docker数据集与自定义镜像:构建高效容器的关键要素
|
3天前
|
Kubernetes Java 调度
Java容器技术:Docker与Kubernetes
Java容器技术:Docker与Kubernetes
13 0
|
3天前
|
存储 缓存 运维
【Docker 专栏】Docker 镜像的分层存储与缓存机制
【5月更文挑战第8天】Docker 镜像采用分层存储,减少空间占用并提升构建效率。每个镜像由多个层组成,共享基础层(如 Ubuntu)和应用层。缓存机制加速构建和运行,通过检查已有层来避免重复操作。有效管理缓存,如清理无用缓存和控制大小,可优化性能。分层和缓存带来资源高效利用、快速构建和灵活管理,但也面临缓存失效和层管理挑战。理解这一机制对开发者和运维至关重要。
【Docker 专栏】Docker 镜像的分层存储与缓存机制
|
3天前
|
存储 测试技术 持续交付
【Docker 专栏】Docker 与 CI/CD 的集成策略
【5月更文挑战第8天】本文探讨了Docker在CI/CD流程中的作用,强调了环境一致性、快速部署和资源隔离等优势。通过在构建、测试和部署阶段集成Docker,可以提升软件开发效率和质量。具体集成策略包括使用Dockerfile构建镜像、整合CI/CD工具如Jenkins和GitLab。集成带来的好处包括提高效率、增强可靠性、加速交付和简化管理。然而,也需应对镜像管理、网络配置和安全等问题。通过案例分析,证明了Docker与CI/CD集成的有效性和必要性。
【Docker 专栏】Docker 与 CI/CD 的集成策略
|
3天前
|
存储 缓存 监控
【Docker 专栏】Docker 容器性能调优实战
【5月更文挑战第8天】本文探讨了Docker容器的性能调优技巧,包括理解容器性能指标(如CPU、内存、网络和磁盘I/O)并进行相应调优。重点讲述了CPU和内存的限制设置,网络配置优化以及磁盘I/O性能提升方法。通过实例展示了如何解决高CPU使用率问题,强调了根据应用需求进行调优的重要性,以实现更高效、稳定的容器运行。
【Docker 专栏】Docker 容器性能调优实战
|
3天前
|
数据库 Docker 容器
【Docker 专栏】使用 Dockerfile 自动化构建 Docker 镜像
【5月更文挑战第8天】Dockerfile是构建Docker镜像的关键,它包含一系列指令,用于描述应用运行环境及所需软件包。通过自动化构建,能提高效率、保证可重复性并提升灵活性。确定基础镜像、安装依赖、设置环境后,执行Dockerfile生成镜像,用于应用程序部署。虽然需要熟悉Docker技术和应用细节,但其带来的益处使其成为现代软件开发和部署的重要工具。
【Docker 专栏】使用 Dockerfile 自动化构建 Docker 镜像