Docker - Dockerfile、数据存储volume、网络通信
概述
上次对 Docker进行单独搭建部署应用服务的实践过程中遇到了三个问题:
- 容器间的网络通信是怎样进行的?当时遇到的问题是使用客户端可以链接,但是用PHP的代码就链接不上。
- 数据和文件的映射?服务的配置文件是怎样进行映射的?镜像中的基本命令是怎么搞的?Dockerfile给了具体的答案。
围绕着Dockerfile、容器的数据、网络的通信进行了一次系统的学习,解决了心里的这些疑惑。如果你想搭建自己的开发部署环境,结合这两篇文章的知识已经足够实践了。
Dockerfile基础镜像的选择
基础镜像的选择(FROM)
基本原则
- 尽量选择官方镜像,如果没有官方镜像,则尽量选择Dockerfile开源的
- 固定版本Tag而不是每次都使用latest
- 尽量选择体积小的镜像
FROM 镜像名字:v1.0
执行命令RUN
RUN 执行指定的命令,尾部用 && \
,可以减少层
文件复制和目录操作(ADD COPY WORKDIR)
WORKDIR /app
WORKDIR 是工作目录选项
构建参数和环境变量(ARG vs ENV)
ARG和ENV都可以用来设置一个变量,但实际上两者有很多不同。
区别:ARG的注重创建镜像,ENV更注重创建后的使用。
容器启动命令(CMD ENTRYPOINT)
CMD可以用来设置容器启动时默认会执行的命令。
- 容器启动时默认执行的命令
- 如果docker run启动时指定了其他命令,则CMD命令被忽略
- 如果定义了多个CMD,只有最后一个会被执行
ENTRYPOINT也可以设置启动时要执行的命令,但是和CMD是有区别的
- CMD设置命令,可以在docker run时传入其他命令,覆盖掉CMD命令,但是ENTRYPOINT所设置的命令是一定会执行的。
- ENTRYPOINT和CMD可以联合使用,ENTRYPOINT设置执行的命令,CMD传递参数。
- 如果当CMD和ENTRYPOINT都存在时,CMD传递的是参数。
支持格式:
- shell格式
- Exec格式
构建Python Flask镜像Demo
FROM python:3.9.5-slim
COPY app.py /src/app.py
RUN pip install falsk
WORKDIR /src
ENV FLASK=app.py
EXPOSE 5000
CMD ["falsk","run","-h","0.0.0.0"]
Dockerfile技巧
1.合理使用缓存
把容易改变的命令放在后面执行,把不易改变的放在前面
2.想办法减少build content的传送空间
Dockerfile目录新建.dockerignore
文件,添加忽略的文件
3.多阶段构建
FROM gcc:9.4 as builder
COPY hello.c /src/hello.c
WORKDIR /src
RUN gcc --static -o hello hello.c
FROM alpine:3.13.5
COPY --from=builder /src/hello /src/hello
ENTRYPOINT [ "/src/hello" ]
CMD []
4.尽量使用非root用户
FROM python:3.9.5-slim
RUN pip install flask && \
groupadd -r flask && useradd -r -g flask flask && \
mkdir /src && \
chown -R flask:flask /src
USER flask
COPY app.py /src/app.py
WORKDIR /src
ENV FLASK=app.py
EXPOSE 5000
CMD ["falsk","run","-h","0.0.0.0"]
官方Dockerfile地址:https://github.com/docker-library/official-images
Docker的存储
Docker主要提供了两种方式做数据的持久化
- Data Volume,由Docker管理,(/var/lib/docker/volume/linux),持久化数据最好的方式
- Bind Mount,由用户指定存储的数据具体mount在系统的什么位置
VOLUME ["/data"]
volume 的命令选项:
Usage: docker volume COMMAND
Manage volumes
Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes
Data Volume 练习Mysql
-v 后面 ,跟踪volume命令
docker run -itd --name mysql2 -p 3326:3306 -e MYSQL_ROOT_PASSWORD=rootroot -v mysql-data:/var/lib/mysql mysql:5.6
产生错误:
docker: Error response from daemon: driver failed programming external connectivity on endpoint mysql4 (4c07f444ad0824e99cd93ccabac2a77acb042e024226567e7869f7b1dfad9fbe): Bind for 0.0.0.0:3326 failed: port is already allocated.
机器之间共享数据
Docker的volume支持多种driver。默认创建的volume driver都是local。
~ docker volume ls
DRIVER VOLUME NAME
local 466bb8597967923a94390044ba506d2aeaeaa3e49d530c728404d85f1f058cfd
local mysql-data
local mysql-data-4
Docker的网络
1.ip地址的查看
Windows:ipconfig
linux:ifconfig
或者 ip addr
2.网络连通性测试
ping ip 或 host
telnet命令
测试端口的连通性 telnet www.baidu.com 80
容器间的通信
bridge模式(网桥模式)
查看docker的网络模式
➜ ~ docker network ls
NETWORK ID NAME DRIVER SCOPE
ad4439ca81c8 bridge bridge local
e3d0267ff307 host host local
3b431f747249 none null local
查看网桥中的服务器节点
docker inspect ad4439ca81c8
原理:容器对内通信,宿主机相当于容器的路由器,进行通信,当容器对外通信时,宿主机进行了一次Nat转换,成功访问外网。
使用前安转brctl
,CentOsyum install -y bridge-utils
,Ubuntuapt-get install -y bridge-utils
创建自定义bridge
docker network create -d bridge mybridge
使用mybridge,在docker run 时,添加参数--network=mybridge
,就可以使用到创建自定义bridge了。
端口转发
如果我们在启动容器时添加-p,Dockerfile中是否添加EXPOSE
定义的端口?EXPOSE是给我们使用镜像中的一个提示。
其他技巧
1.批量操作docker镜像
docker rm $(docker ps -aq)
2.容器的attached和detached模式
- attached模式:Docker镜像前台模式运行
- detached模式:Docker容器后台执行
在服务的启动中参数用-d
的就是detached模式的意思。
3.删除所有退出的容器
docker system prune -f
4.删除没有使用的镜像
docker image prune -a
5.查看镜像的历史记录
docker image history stark_lnmp:v1.0
6.如果启动镜像时添加--rm
,当容器退出时自动删除容器
docker run --rm -it 7d63a5989e81 bash
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?