spring cloud docker容器化

spring cloud docker插件自动化部署

Spring Boot使用DockerFile maven插件自动化部署
参URL; https://blog.csdn.net/liubingyu12345/article/details/79015966
Spring Boot with Docker
官方参考URL: https://spring.io/guides/gs/spring-boot-docker/

通用步骤

  1. dockerfile-maven-plugin插件入门
    docker-maven-plugin 插件默认连接本地 Docker 地址为:localhost:2375,所以我们需要先设置下环境变量。
DOCKER_HOST=tcp://<host>:2375

Dockerfile Maven的特性

  • 默认,构建Dockerfile的过程包含在mvn package阶段;
  • 默认,为Dockerfile打标签的过程包含在mvn package阶段;
  • 默认,发布Dockerfile的过程包含在mvn deploy阶段;

mvn dockerfile:build
mvn dockerfile:tag
mvn dockerfile:push

构建Docker项目时,直接执行mvn deploy即可构建并发布Dockerfile文件到Maven本地库。

  1. 添加docker插件依赖添加docker插件依赖
    插件官方地址: https://github.com/spotify/dockerfile-maven
    Maven有个插件,叫dockerfile-maven-plugin,它会连接远程Docker,只要一个命令就能把本地的jar包打成Docker镜像,命令执行完毕后,服务器上就会有刚打包好的镜像,此时再执行该镜像即可。
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>

      <!--dockerfile-maven-plugin插件-->
      <plugin>
        <groupId>com.spotify</groupId>
        <artifactId>dockerfile-maven-plugin</artifactId>
        <version>${dockerfile-maven-version}</version>
        <configuration>
          <repository>${docker.image.prefix}/${project.artifactId}</repository>
          <tag>${project.version}</tag>
          <buildArgs>
            <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
          </buildArgs>
        </configuration>
      </plugin>

    </plugins>
  </build>

至此你可以构建一个有tagged的docker的镜像,使用命令

$ ./mvnw dockerfile:build

你也可以push这个镜像到仓库

./mvnw dockerfile:push

mvnw全名是Maven Wrapper,是对mvn的封装,没有引入mvnw时候,你可以直接使用mvn。

至此,你已经可以使用mvn命令手动直接打包镜像了,也可以使用IDEA的界面maven界面操作。
spring cloud docker容器化

如何把构建镜像、和推送镜像放到你maven的生命周期中呢?pom插件plugin配置项加入如下配置项:
you can make dockerfile:push automatically run in the install or deploy lifecycle phases by adding it to the plugin configuration.
你可以根据需要,添加不同配置项:

<executions>
	<execution>
		<id>default</id>
		<phase>install</phase>
		<goals>
			<goal>build</goal>
			<goal>push</goal>
		</goals>
	</execution>
</executions>

打包时,构建镜像:

        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>build</goal>
            </goals>
          </execution>
        </executions>```

phase元素代表的是绑定的生命周期的阶段
goals 元素代表插件的目标 插件是你前面artifactId中定义好的 goals相当于该插件中的一个功能 该功能将在phase绑定的生命周期阶段执行。
goal是一个插件的具体功能 而不是一个阶段 phase才是。

遇到问题整理

  1. mvn命令构建docker镜像报错 ADD failed: stat /var/lib/docker/tmp/
    原因分析:
    这里的提醒路径/var/lib/docker/tmp/应该是指Docker宿主机,
    maven docker插件应该是根据你的配置<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> 从这里先copy到Docker宿主机的/var/lib/docker/tmp/xxx 目录,然后才从Docker宿主机复制到Docker容器中。所以这个配置要配置正确,出问题优先检查这个配置,让maven docker插件可以找到。
  • ADD user-server-0.0.1-SNAPSHOT.jar app.jar 要和pom的user-server
    工程的pom.xml 和Dockerfile配置不一致
    保持名字一样,不然maven打出来的包,docker找不到。
  • 第二点 <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
    的配置要注意,第一我
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>

      <!--dockerfile-maven-plugin插件-->
      <plugin>
        <groupId>com.spotify</groupId>
        <artifactId>dockerfile-maven-plugin</artifactId>
        <version>${dockerfile-maven-version}</version>
        <configuration>
          <repository>${docker.image.prefix}/${project.artifactId}</repository>
          <tag>${project.version}</tag>
          <buildArgs>
            <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
          </buildArgs>
        </configuration>
      </plugin>

    </plugins>
  </build>

Dockerfile 常用指令

  1. FROM
    指定 base 镜像。

  2. MAINTAINER
    设置镜像的作者,可以是任意字符串。

  3. COPY
    将文件从 build context 复制到镜像。
    COPY 支持两种形式:

    COPY src dest

    COPY [“src”, “dest”]
    注意:src 只能指定 build context 中的文件或目录

  4. ADD
    与 COPY 类似,从 build context 复制文件到镜像。不同的是,如果 src 是归档文件(tar, zip, tgz, xz 等),文件会被自动解压到 dest。

  5. ENV
    设置环境变量,环境变量可被后面的指令使用。例如:

ENV MY_VERSION 1.3

RUN apt-get install -y mypackage=$MY_VERSION


6. EXPOSE
指定容器中的进程会监听某个端口,Docker 可以将该端口暴露出来。

Dockerfile中不管有没有EXPOSE端口,需要新增端口映射只能restart container。
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。

在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。

要将 EXPOSE 和在运行时使用 -p <宿主端口>:<容器端口> 区分开来。-p,是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射

经测试,好像声明了EXPOSE -P 也不会帮你自动映射。

  1. VOLUME
    没有声明EXPOSE端口的情况下使用-p是有效的。但是要注意VOLUME和EXPOSE不同,一旦Dockerfile中有VOLUME, 在docker run的时候,,docker 始终会将host中的目录挂载到VOLUME声明的目录并会将VOLUME声明之前的内容复制到挂载上的目录。

VOLUME 指向了一个/tmp的目录,由于 Spring Boot 使用内置的Tomcat容器,Tomcat 默认使用/tmp作为工作目录。这个命令的效果是:在宿主机的/var/lib/docker目录下创建一个临时文件并把它链接到容器中的/tmp目录VOLUME ,VOLUME 指向了一个/tmp的目录,由于 Spring Boot 使用内置的Tomcat容器,Tomcat 默认使用/tmp作为工作目录。这个命令的效果是:在宿主机的/var/lib/docker目录下创建一个临时文件并把它链接到容器中的/tmp目录VOLUME 指向了一个/tmp的目录,由于 Spring Boot 使用内置的Tomcat容器,Tomcat 默认使用/tmp作为工作目录。这个命令的效果是:在宿主机的/var/lib/docker目录下创建一个临时文件并把它链接到容器中的/tmp目录VOLUME ,VOLUME 指向了一个/tmp的目录,由于 Spring Boot 使用内置的Tomcat容器,Tomcat 默认使用/tmp作为工作目录。这个命令的效果是:在宿主机的/var/lib/docker目录下创建一个临时文件并把它链接到容器中的/tmp目录
8. WORKDIR
为后面的 RUN, CMD, ENTRYPOINT, ADD 或 COPY 指令设置镜像中的当前工作目录。
9. RUN
在容器中运行指定的命令。
10. ENTRYPOINT
设置容器启动时运行的命令。
Dockerfile 中可以有多个 ENTRYPOINT 指令,但只有最后一个生效。CMD 或 docker run 之后的参数会被当做参数传递给 ENTRYPOINT。

为了缩短 Tomcat 的启动时间,添加java.security.egd的系统属性指向/dev/urandom作为 ENTRYPOINT为了缩短 Tomcat 的启动时间,添加java.security.egd的系统属性指向/dev/urandom作为 ENTRYPOINT

问题整理

  1. Spring Cloud Config Server迁移节点或容器化带来的问题
    参考URL: https://segmentfault.com/a/1190000015018651?utm_source=tag-newest