上次对 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 volumesData 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-4Docker的网络
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
创建自定义bridgedocker 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



