先不说Dockerfile
是什么,通过一个案例体会一下Dockerfile
使用。在 Mac OS
系统上,根据官方的tomcat
容器定制一个tomcat
容器,效果如下:
- 编写定制文件
index.html 文件内容:
Hi,Docker
文件目录结构如下图所示:
- 编写
Dockerfile
文件
# 设置基准镜像,然后在这个基准镜像上进行定制化开发
FROM tomcat:latest
# 设置镜像拥有者信息
LABEL maintainer="DaFei"
# 用于执行命令
RUN rm -rf /usr/local/tomcat/webapps
RUN mv /usr/local/tomcat/webapps.dist /usr/local/tomcat/webapps
# 切换工作目录,不存在则创建
# /usr/local/tomcat/webapps 是 tomcat 部署应用的目录
WORKDIR /usr/local/tomcat/webapps
# 第一个 docker-web 指的是 Dockerfile 同级目录下的 docker-web 目录
# ADD 命令就是将 docker-web 目录下内容复制到容器的 docker-web 目录
ADD docker-web ./docker-web
- 构建容器并启动
(1)进入到 dockerfile-01
目录下执行构建命令
/Users/shifeifei/sff/project/docker-example/dockerfile-01
docker build -t dafei/webapp:1.0 .
(2)启动容器,注意指定映射端口
docker run -d -p 8081:8080 dafei/webapp:1.0
- 浏览器访问
这里访问要使用的映射端口 8081; http://localhost:8081/docker-web/index.html
总结: Dockerfile
就是用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
一、Dockerfile
命令
1. 基础指令
命令 | 作用 | 示例 |
---|---|---|
FROM | 依赖的基础镜像 | FROM centos |
LABEL | 说明信息 | LABEL maintainer="DaFei" LABEL version="1.0" LABEL description="定制tomcat" |
WORKDIR | 设置工作目录 | 1. WORKDIR /usr/local/my 2.推荐使用绝对路径 |
ADD | 复制文件 | 1. ADD hello / :将hello文件复制到容器的根目录下 2. ADD test.gz / :在根目录直接解压文件 |
ENV | 设置环境常量 | 1.ENV JAVA_HOME /usr/local/openjdk8 2. RUN ${JAVA_HOME}/bin/java -jar test.jar 设置环境常量可以提供程序的可维护性,当路径改变时,只需要改变一出即可 |
EXPOSE | 当前容器启动后对外暴露的端口声明 |
2. 运行指令
命令 | 作用 | 示例 |
---|---|---|
RUN | 在构建时执行命令,修改镜像的内容 | 1. Shell命令格式:RUN yum install -y vim 2. Exec命令格式:RUN ["yum","install","y","vim"] |
ENTRYPOINT | 容器启动时执行命令 | 1. 如果Dockerfile 中有多行ENTRYPOINT ,最后一行一定会被执行,推荐使用Exec命令格式 2. ENTRYPOINT ["ps"] |
CMD | 容器启动后执行默认的命令或参数 | 1. CMD不一定会被执行,比如 docker run test/my_docker ls ,此时因为docker run 启动容器的命令后面又有其他命令,所以Dockerfile 文件有CMD 时就不会执行 |
这三个命令执行时机是不同的,如下图所示: |
3. ENTRYPOINT + CMD
命令的组合使用
构建Dockerfile
文件
FROM centos
RUN ["echo","image building !!!"]
ENTRYPOINT ["ps"]
CMD ["-ef"]
执行命令:
docker pull centos
docker build -t dafei/docker_cmd:1.0 .
docker run dafei/docker_cmd:1.0
运行后的结果:
CMD
的一个优势就是能够被覆盖,不需要去修改 Dockerfile
文件中的命令,比如执行如下命令:
docker run dafei/docker_cmd:1.0 -aux
二、基于 Centos 制作 Redis 容器
1. 准备工作
-
准备目录
-
下载redis官方压缩包
redis-4.0.14.tar.gz
-
设置redis配置
redis-6379.conf
port 6379
bind 0.0.0.0
2.编写 Dockerfile 文件
FROM centos
# 解决 centos8 停止服务问题开始
RUN cd /etc/yum.repos.d/
RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
RUN yum update -y
# 解决 centos8 停止服务问题命令结束
RUN ["yum" , "install" , "-y" , "gcc" , "gcc-c++" , "net-tools" , "make" ]
WORKDIR /usr/local
# 将文件解压到 /usr/local 目录下
ADD redis-4.0.14.tar.gz .
WORKDIR /usr/local/redis-4.0.14/src
RUN make && make install
WORKDIR /usr/local/redis-4.0.14
# 将 redis 配置文件放到 /usr/local/redis-4.0.14 目录下
ADD redis-6379.conf .
EXPOSE 6379
CMD ["redis-server","redis-6379.conf"]
注意: 该文件中有一段命令时来解决 centos 停服问题,不然会报错
1.167 CentOS Linux 8 - AppStream 67 B/s | 38 B 00:00
1.173 Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
executor failed running [yum install -y gcc gcc-c++ net-tools make]: exit code: 1
3. 构建并运行
docker build -t dafei/docker_redis:1.0 .
docker run -p 6379:6379 dafei/docker_redis:1.0
4. 宿主机上使用客户端连接redis
实际开发环境中是并不需这么制作 redis 容器的,Docker 官方已经为我们提供好了相关的 redis 容器,只需要使用 docker pull 命令拉取即可。
三、容器间通信
Docker 会为每一个容器提供虚拟IP,如何查看容器的虚拟IP,使用 docker inspect
命令,比如查看dafei/docker_redis:1.0
容器IP
docker inspect aaa5032bc573
1. 容器间的单向访问
如图所示,如果Tomcat容器
要访问MySQL容器
,通过虚拟IP容器之间是可以相互通信的,但是如果容器虚拟IP改变之后,再通信的话需要知道新的IP,这就比较麻烦了!在 Docker 中提供了通过容器名称通信的功能来解决该问题。
- 启动两个容器
docker run -d --name database -it centos /bin/bash
,由于centos容器启动后会自动退出,所以为了解决这个问题,加了参数 -it
用交互模式启动,并且需要加上 /bin/bash
命令
(1) 该容器的虚拟IP是 172.17.0.4
docker run -d --name web-service tomcat
(1) 该容器的虚拟IP是 172.17.0.3
注意:如果ping命令执行时报错 bash: ping: command not found,依次执行如下命令即可
apt-get update
apt-get install iputils-ping
(2)如何通过容器名称来通信?
删除容器 web-service ,重新用如下命令启动容器
docker run -d --name web-service --link database tomcat
2. 基于网桥(Bridge)容器间的双向通信
docker network ls
此时看到有一个默认的 Bridge,为了实现容器双向通信,我们需要再创建一个自己的 Bridge
- 创建 Bridge
docker network create -d bridge user-bridge
- 在 user-bridge 网桥上绑定容器
docker network connect user-bridge web-service
docker network connect user-bridge database
(1)验证是否双向通信
(2)网桥实现双向通信原理
四、容器间数据共享
Docker
容器可以通过数据容器卷实现容器间的数据共享
1. 通过 -v
设置挂载目录
docker run --name 容器名称 -v 宿主机路径:容器内挂载路径 镜像名称
案例:
docker run --name test -v /usr/webapps:/usr/local/tomcat/webapps tomcat
2. 通过--volumes-from
共享容器内挂载点
- 创建共享容器
docker create --name common-volumes -v /webapps:/tomcat/webapps tomcat /bin/true
创建一个共享容器,并且设置挂载目录/webapps:/tomcat/webapps
,但不运行该容器
- 共享容器挂载点
docker run --volumes-from common-volumes --name test -d tomcat
启动容器 test,并设置共享挂载点到共享容器 common-volumes 中