【Docker】自定义镜像与Compose

叁歲伎倆 2024-03-26 13:37 165阅读 0赞

目录

2.3.6.案例-给MySQL挂载本地目录

2.3.7.小结

3.Dockerfile自定义镜像

3.1.镜像结构

3.2.Dockerfile语法

3.3.构建Java项目

3.3.1.基于Ubuntu构建Java项目

3.3.2.基于java8构建Java项目

3.4.小结

4.Docker-Compose

4.1.初识DockerCompose

4.2.安装DockerCompose

4.3.部署微服务集群

4.3.1.compose文件

4.3.2.修改微服务配置

4.3.3.打包

4.3.4.拷贝jar包到部署目录

4.3.5.部署

5.Docker镜像仓库

5.1.搭建私有镜像仓库

5.2.推送、拉取镜像

2.3.6.案例-给MySQL挂载本地目录

容器不仅仅可以挂载数据卷,也可以直接挂载到宿主机目录上。关联关系如下:

  • 带数据卷模式:宿主机目录 —> 数据卷 —-> 容器内目录
  • 直接挂载模式:宿主机目录 —-> 容器内目录

如图:

36885d06ec464eb390846390a22e6e1b.png

语法

目录挂载与数据卷挂载的语法是类似的:

  • -v [宿主机目录]:[容器内目录]
  • -v [宿主机文件]:[容器内文件]

需求:创建并运行一个MySQL容器,将宿主机目录直接挂载到容器

实现思路如下:

1)在将课前资料中的mysql.tar文件上传到虚拟机,通过load命令加载为镜像

2)创建目录/tmp/mysql/data

3)创建目录/tmp/mysql/conf,将课前资料提供的hmy.cnf文件上传到/tmp/mysql/conf

4)去DockerHub查阅资料,创建并运行MySQL容器,要求:

① 挂载/tmp/mysql/data到mysql容器内数据存储目录

② 挂载/tmp/mysql/conf/hmy.cnf到mysql容器的配置文件

③ 设置MySQL密码

2.3.7.小结

docker run的命令中通过 -v 参数挂载文件或目录到容器中:

  • -v volume名称:容器内目录
  • -v 宿主机文件:容器内文
  • -v 宿主机目录:容器内目录

数据卷挂载与目录直接挂载的

  • 数据卷挂载耦合度低,由docker来管理目录,但是目录较深,不好找
  • 目录挂载耦合度高,需要我们自己管理目录,不过目录容易寻找查看

3.Dockerfile自定义镜像

常见的镜像在DockerHub就能找到,但是我们自己写的项目就必须自己构建镜像了。

而要自定义镜像,就必须先了解镜像的结构才行。

3.1.镜像结构

镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而成。

我们以MySQL为例,来看看镜像的组成结构:

ad6e818336714250babf948aaff4b251.png

简单来说,镜像就是在系统函数库、运行环境基础上,添加应用程序文件、配置文件、依赖文件等组合,然后编写好启动脚本打包在一起形成的文件。

我们要构建镜像,其实就是实现上述打包的过程。

3.2.Dockerfile语法

构建自定义的镜像时,并不需要一个个文件去拷贝,打包。

我们只需要告诉Docker,我们的镜像的组成,需要哪些BaseImage、需要拷贝什么文件、需要安装什么依赖、启动脚本是什么,将来Docker会帮助我们构建镜像。

而描述上述信息的文件就是Dockerfile文件。

Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。

e1f7b60d94f74e4d87c3910454def004.png

更新详细语法说明,请参考官网文档: Dockerfile reference

3.3.构建Java项目

3.3.1.基于Ubuntu构建Java项目

需求:基于Ubuntu镜像构建一个新镜像,运行一个java项目

  • 步骤1:新建一个空文件夹docker-demo

    a4f2fd1fff4b4c91ae7d0087b978130e.png

  • 步骤2:拷贝课前资料中的docker-demo.jar文件到docker-demo这个目录

    5566a4dc708a4f8db64bbc0e596b3336.png

  • 步骤3:拷贝课前资料中的jdk8.tar.gz文件到docker-demo这个目录

    eacffc20f34f436a97d8a76217df99fa.png

  • 步骤4:拷贝课前资料提供的Dockerfile到docker-demo这个目录

    6ba9a27dc6684aa6bbddd515fa1d2394.png

    其中的内容如下:

    1. # 指定基础镜像
    2. FROM ubuntu:16.04
    3. # 配置环境变量,JDK的安装目录
    4. ENV JAVA_DIR=/usr/local
    5. # 拷贝jdk和java项目的包
    6. COPY ./jdk8.tar.gz $JAVA_DIR/
    7. COPY ./docker-demo.jar /tmp/app.jar
    8. # 安装JDK
    9. RUN cd $JAVA_DIR \
    10. && tar -xf ./jdk8.tar.gz \
    11. && mv ./jdk1.8.0_144 ./java8
    12. # 配置环境变量
    13. ENV JAVA_HOME=$JAVA_DIR/java8
    14. ENV PATH=$PATH:$JAVA_HOME/bin
    15. # 暴露端口
    16. EXPOSE 8090
    17. # 入口,java项目的启动命令
    18. ENTRYPOINT java -jar /tmp/app.jar
  • 步骤5:进入docker-demo

    将准备好的docker-demo上传到虚拟机任意目录,然后进入docker-demo目录下

  • 步骤6:运行命令:

    1. docker build -t javaweb:1.0 .

最后访问 http://192.168.150.101:8090/hello/count,其中的ip改成你的虚拟机ip

3.3.2.基于java8构建Java项目

虽然我们可以基于Ubuntu基础镜像,添加任意自己需要的安装包,构建镜像,但是却比较麻烦。所以大多数情况下,我们都可以在一些安装了部分软件的基础镜像上做改造。

例如,构建java项目的镜像,可以在已经准备了JDK的基础镜像基础上构建。

需求:基于java:8-alpine镜像,将一个Java项目构建为镜像

实现思路如下:

  • ① 新建一个空的目录,然后在目录中新建一个文件,命名为Dockerfile
  • ② 拷贝课前资料提供的docker-demo.jar到这个目录中
  • ③ 编写Dockerfile文件:

    • a )基于java:8-alpine作为基础镜像
    • b )将app.jar拷贝到镜像中
    • c )暴露端口
    • d )编写入口ENTRYPOINT

      内容如下:

      1. FROM java:8-alpine
      2. COPY ./app.jar /tmp/app.jar
      3. EXPOSE 8090
      4. ENTRYPOINT java -jar /tmp/app.jar
  • ④ 使用docker build命令构建镜像
  • ⑤ 使用docker run创建容器并运行

3.4.小结

小结:

  1. Dockerfile的本质是一个文件,通过指令描述镜像的构建过程
  2. Dockerfile的第一行必须是FROM,从一个基础镜像来构建
  3. 基础镜像可以是基本操作系统,如Ubuntu。也可以是其他人制作好的镜像,例如:java:8-alpine

4.Docker-Compose

Docker Compose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器!

98cceb23abb9491db3b47f69fd742417.png

4.1.初识DockerCompose

Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。格式如下:

  1. version: "3.8"
  2. services:
  3. mysql:
  4. image: mysql:5.7.25
  5. environment:
  6. MYSQL_ROOT_PASSWORD: 123
  7. volumes:
  8. - "/tmp/mysql/data:/var/lib/mysql"
  9. - "/tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf"
  10. web:
  11. build: .
  12. ports:
  13. - "8090:8090"

上面的Compose文件就描述一个项目,其中包含两个容器:

  • mysql:一个基于mysql:5.7.25镜像构建的容器,并且挂载了两个目录
  • web:一个基于docker build临时构建的镜像容器,映射端口时8090

DockerCompose的详细语法参考官网:Compose file specification

其实DockerCompose文件可以看做是将多个docker run命令写到一个文件,只是语法稍有差异。

4.2.安装DockerCompose

参考课前资料

4.3.部署微服务集群

需求:将之前学习的cloud-demo微服务集群利用DockerCompose部署

实现思路

① 查看课前资料提供的cloud-demo文件夹,里面已经编写好了docker-compose文件

② 修改自己的cloud-demo项目,将数据库、nacos地址都命名为docker-compose中的服务名

③ 使用maven打包工具,将项目中的每个微服务都打包为app.jar

④ 将打包好的app.jar拷贝到cloud-demo中的每一个对应的子目录中

⑤ 将cloud-demo上传至虚拟机,利用 docker-compose up -d 来部署

4.3.1.compose文件

查看课前资料提供的cloud-demo文件夹,里面已经编写好了docker-compose文件,而且每个微服务都准备了一个独立的目录:

9fcfa02479b14468b17f4a61854f5c92.png

内容如下:

  1. version: "3.2"
  2. services:
  3. nacos:
  4. image: nacos/nacos-server
  5. environment:
  6. MODE: standalone
  7. ports:
  8. - "8848:8848"
  9. mysql:
  10. image: mysql:5.7.25
  11. environment:
  12. MYSQL_ROOT_PASSWORD: 123
  13. volumes:
  14. - "$PWD/mysql/data:/var/lib/mysql"
  15. - "$PWD/mysql/conf:/etc/mysql/conf.d/"
  16. userservice:
  17. build: ./user-service
  18. orderservice:
  19. build: ./order-service
  20. gateway:
  21. build: ./gateway
  22. ports:
  23. - "10010:10010"

可以看到,其中包含5个service服务:

  • nacos:作为注册中心和配置中心

    • image: nacos/nacos-server: 基于nacos/nacos-server镜像构建
    • environment:环境变量

      • MODE: standalone:单点模式启动
    • ports:端口映射,这里暴露了8848端口
  • mysql:数据库

    • image: mysql:5.7.25:镜像版本是mysql:5.7.25
    • environment:环境变量

      • MYSQL_ROOT_PASSWORD: 123:设置数据库root账户的密码为123
    • volumes:数据卷挂载,这里挂载了mysql的data、conf目录,其中有我提前准备好的数据
  • userserviceorderservicegateway:都是基于Dockerfile临时构建的

查看mysql目录,可以看到其中已经准备好了cloud_order、cloud_user表:

350c6214400d48049aa2f7ecba6db92f.png

查看微服务目录,可以看到都包含Dockerfile文件:

01152f95e6c5493aa2717a7c1204e175.png

内容如下:

  1. FROM java:8-alpine
  2. COPY ./app.jar /tmp/app.jar
  3. ENTRYPOINT java -jar /tmp/app.jar

4.3.2.修改微服务配置

因为微服务将来要部署为docker容器,而容器之间互联不是通过IP地址,而是通过容器名。这里我们将order-service、user-service、gateway服务的mysql、nacos地址都修改为基于容器名的访问。

如下所示:

  1. spring:
  2. datasource:
  3. url: jdbc:mysql://mysql:3306/cloud_order?useSSL=false
  4. username: root
  5. password: 123
  6. driver-class-name: com.mysql.jdbc.Driver
  7. application:
  8. name: orderservice
  9. cloud:
  10. nacos:
  11. server-addr: nacos:8848 # nacos服务地址

4.3.3.打包

接下来需要将我们的每个微服务都打包。因为之前查看到Dockerfile中的jar包名称都是app.jar,因此我们的每个微服务都需要用这个名称。

可以通过修改pom.xml中的打包名称来实现,每个微服务都需要修改:

  1. <build>
  2. <!-- 服务打包的最终名称 -->
  3. <finalName>app</finalName>
  4. <plugins>
  5. <plugin>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-maven-plugin</artifactId>
  8. </plugin>
  9. </plugins>
  10. </build>

打包后:

c6535995c3914484a3dda9f2ed846ef5.png

4.3.4.拷贝jar包到部署目录

编译打包好的app.jar文件,需要放到Dockerfile的同级目录中。注意:每个微服务的app.jar放到与服务名称对应的目录,别搞错了。

user-service:

d53dfa8f9ca74024b4d9f3f801f0d5bf.png

order-service:

d848703ffc354549a9985e51c09fa7fa.png

gateway:

9b7640572f5a49a2abb3589b88b495e9.png

4.3.5.部署

最后,我们需要将文件整个cloud-demo文件夹上传到虚拟机中,理由DockerCompose部署。

上传到任意目录:

ce9da65a7592431c929ca9be7118397f.png

部署:

进入cloud-demo目录,然后运行下面的命令:

  1. docker-compose up -d

5.Docker镜像仓库

5.1.搭建私有镜像仓库

参考课前资料《CentOS7安装Docker.md》

5.2.推送、拉取镜像

推送镜像到私有镜像服务必须先tag,步骤如下:

① 重新tag本地镜像,名称前缀为私有仓库的地址:192.168.150.101:8080/

  1. docker tag nginx:latest 192.168.150.101:8080/nginx:1.0

② 推送镜像

  1. docker push 192.168.150.101:8080/nginx:1.0

③ 拉取镜像

  1. docker pull 192.168.150.101:8080/nginx:1.0

发表评论

表情:
评论列表 (有 0 条评论,165人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Docker(二) 定义镜像

    一、前言 记得上半年有一个需求是给服务(mysql)兼容oracle数据库,之前没有怎么接触过oracle数据库,也没有安装过,于是从同事那里要来了安装包(windows