1. 端口映射以及容器互联
Docker 除了通过网络访问,还提供了两种很方便的功能来满足服务访问的基本需求:
- 允许映射容器内应用的服务端口到本地宿主主机
- 互联机制实现多个容器间通过容器名来快速访问
1.1 容器映射实现访问容器
1.1.1 从外部访问容器应用
当容器中运行一些网络应用时,可以通过-P
或者-p
来指定端口映射。-P
会使Docker随机取一个端口号。
docker run -d -P training/webapp python app.py
表示本地主机的32769映射到了容器的5000端口
你也可以使用-p
来指定端口绑定一个容器,格式:
HOSTPort:ContainerPort 或者 IP::ContainerPort
1.1.2 映射所有接口端口
docker run -d -p 5000:5000 training/webapp python app.py // 将本地的5000端口映射到容器的5000端口
也可以一次绑定多个端口
docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py // 将本地的5000端口映射到容器的5000端口,且本地3000端口也映射到容器的80端口
1.1.3 映射到指定地址的指定端口
docker -run -d -p127.0.0.1:5000:5000 training/webapp python app.py
此处用的就是ip:HOSTPORT:ContainerPort
格式指定映射地址
1.1.4 映射到指定容器的任意端口
docker run -d -p 127.0.0.1::5000 training/webapp python app.py
此处用的就是IP::ContainerPort
绑定本地主机任意端口到容器5000端口
docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
还可以使用udp标记来指定udp端口
1.1.5 查看映射端口的配置
docker port ContainerName
注意:
容器有自己的内部网络和IP地址,使用docker inspect + 容器ID 可以获取容器的具体信息
1.2 互联机制实现便捷互访
容器的互联会在源和接受容器之间创建链接关系,接受容器可以通过容器名快速访问到源容器,而不用制定具体的IP地址
1.2.1 自定义容器命名
docker run -d -P --name web training/webapp python app.py
使用--name
可以自定义容器名,以上就命名容器为web
docker ps -l 来验证
docker inspect -f "{{ .Name }}" [容器ID]
容器的名称是唯一的,如果你已经有了一个名为web的容器,你就不能创建一个相同名字的容器了,必须先rm在创建,如果在docker run使用--rm标记,那么会在容器终止后立即删除,
注意--rm和-d参数不能同时使用
1.2.2 容器互联
创建容器:
docker run -d --name db training/postgres // 创建一个数据库容器
docker rm -f web // 删除之前的web容器
docker run -d -P --name web --link db:db training/webapp python app.py // 然后创建一个web容器,并且把他连接到db容器
此时。db容器和web容器为互联关系。 --link
参数格式为--link name:alias
其中name是链接容器名称,alias是这个链接的别名。
注意: Docker相当于在两个容器之间创建了一个虚拟通道,而不需要再去映射它们的端口到宿主主机上。在启动db容器的时候没有使用-p
或-P
标记,从而避免数据库服务端口暴露到外部网络中。
我们来测试两者之间连通性:
docker run -t -i --rm --link db:db training/webapp /bin/bash // 进入终端
cat /etc/host
ping db
这里我们可以看到db被解析成了172.18.0.3
2. 使用Dockerfile创建镜像
2.1 基本结构
Dockerfile主要分为四个部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令
例子:
Dockerfile
FROM ubuntu // 所创建的基础镜像信息
MAINTAINER docker_user docker_user@email.com // 维护者信息
RUN echo "deb http://archive.ubuntu.com/ubuntu raring main universe" >> /etc/apt/sources.list // 运行命令
RUN yum -y nginx // 运行命令
RUN echo "\ndaemmon off;" >> /etc/nginx/nginx.conf // 运行命令
CMD /usr/bin/nginx // 启动容器时的默认指令
2.2 指令说明
2.2.1 FROM
解释: 指定所创建镜像的基础镜像,如果本地不存在,则默认会去Docker Hub下载指定镜像
格式:
FROM[image] | [image]:[tag] | [image]@[digest]
注意:Dockerfile第一条指令必须是FROM指令,如果在同一个Dockerfile中创建多个镜像,可以使用多个FROM指令(每个镜像一次)
2.2.2 MAINTAINER
解释: 指定维护者信息。
格式:
MAINTAINER image_creator@docker.com
生成的镜像会写入镜像的Author属性域中。
2.2.3 RUN
解释: 运行指定命令。
格式:
RUN [command] | ["executable","param1","param2"]
注意!上面第二种方式会被解析成一个JSON,所以必须使用双引号
RUN可以使用\来进行换行
2.2.4 CMD
解释: 用来指定启动容器时默认执行的命令
格式:
CMD ["executable","param1","param2"] | command param1 param2 | ["param1","param2"]
其中第一种是使用exec执行,是最推荐的方式,第二种是提供给需要交互的应用,第三种是提供给ENTRYPOINT
的默认参数
每一个Dockerfile只能有一条CMD命令,如果指定了多条,只有最后一条会执行
如果启动容器的时候手动指定了运行命令(RUN)则会覆盖掉CMD命令
2.2.5 LABEL
解释: 用来指定生成镜像的元数据标签信息。
格式:
LABEL [key]=[value] [key]=[value] ...
2.2.6 EXPOSE
解释: 声明镜像内服务监听的端口
格式:
EXPOSE 22 80 8080
注意:
该指令只是起到声明作用,并不会自动完成端口映射。
在启动容器时,需要使用-P,Docker主机会自动分配一个宿主机的临时端口转发到指定端口
使用-p,可以具体声明从宿主机哪个本地端口映射过来
2.2.7 ENV
解释: 指定环境变量,在镜像生成过程中会被后续的RUN指令使用,在镜像启动的容器中也会存在。
格式:
ENV [key][value] | [key] = [value]
指令指定的环境变量在运行时可以被覆盖掉,如:
docker run --env [key]=[value] ...
2.2.8 ADD
解释: 复制指定的src
路径下的内容到容器中的dest
路径下
格式:
add [src][dest]
如果是tar文件,会自动解压到dest路径下,dest可以是绝对路径,或者是对于工作目录的相对路径。
2.2.9 COPY
解释: 复制本地主机的src
到镜像容器的dest
下,注意!和add是有区别的
,copy主要复制的是本地主机
。
格式:
copy [src][dest]
2.2.10 ENTRYPOINT
解释: 指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,所有传入值作为该命令的参数
格式:
ENTRYPOINT ["executable","param1","param2"]
ENTRYPOINT command param1 param2
前者使用exec调用,后者在shell中执行。使用后CMD指令指定值将作为根命令的参数
每个Dockerfile中只能有一个ENTRYPOINT,当有多个时,只有最后一个有效。
在运行时,可以被 --entrypoint覆盖掉
2.2.11 VOLUME
**解释:**创建一个数据卷挂载点。
格式:
VOLUMe["/data"]
2.2.12 USER
解释: 指定容器运行时的用户名或ID,后续RUN也会指定用户身份。
格式:
USER daemon
当服务不需要管理员时,也可以通过命令来指定运行用户,并且可以在之前创建所需要的用户。
RUN groupadd -r postgres && useradd -r -g postgres postgres
2.2.13 WORKDIR
解释: 为后续的RUN、CMD和ENTRYPOINT指令配置工作目录
格式:
WORKDIR [path]
2.2.14 ARG
解释: 指定一些镜像内使用的参数
格式:
ARG [name][=[default name]]
2.2.15 ONBUILD
解释: 配置当所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作指令
ONBUILD [INSTRUCTION]
2.2.16 STOPSIGNAL
解释: 指定所创建镜像启动的容器接受退出的信号值
格式:
STOPSIGNAL [signal]
2.2.17 HEALTHCHECK
**解释: ** 配置所启动容器如何进行健康检查
格式:
HEALTHCHECK [OPTIONS] CMD command; // 根据所执行命令返回值是否为0判断
HEALTHCHECK NONE; // 禁止进行健康检查
OPTIONS选项说明:
指令 | 解释 |
---|---|
--interval | 默认30s,过多久检查一次 |
--timeout | 默认30s,每次检查等待结果的超时时间 |
--retries | 默认3,检查失败了,重试几次才确定 |
2.2.18 SHELL
解释: 其他命令使用shell时的默认shell类型
格式:
shell ["command","options"]
注意:Dockerfile开头添加#escape=来指定转义信息
2.3 创建镜像
Dockerfile通过docker build
来创建镜像。
例如,指定Dockerfile所在路径为 /tmp/docker_builder/
,希望生成的标签为build_repo/first_iamge
。
docker build -t build_repo/first_iamge /tmp/docker_builder/
2.4 使用.dockerignore文件
可以通过.dockerignore
来让Docker忽略匹配模式下路径的目录和文件
2.5 最佳实践
遵循一下九条意见:
- 精简镜像用途
- 选用合适的基础镜像
- 提供足够清晰的命令注释和维护者信息
- 正确使用版本号
- 减少镜像层数
- 及时删除临时文件和缓存文件
- 提高生成速度
- 调整合理的指令顺序
- 减少外部源干扰
总结
本章节主要介绍了Docker容器如何进行互通,以及容器互通时需要注意的事项以及细节,然后详细的介绍了Dockerfile各个关键字的含义,以及如何使用,到这里Docker入门的章节就结束了,后面会有一个Docker实战篇。