docker学习---第3步:docker实操大模型
文章目录
- 1.Images
- 2.Container
- 3.Dockerfile
- ENTRYPOINT和CMD
- COPY和ADD
- LABLE、EXPOSE和VOLUME
- 卷中的数据是如何做数据备份的?
- ARG和ENV
- HEALTHCHECK
- 4. Network(本节讲容器与容器之间的通信方案)
跟着b站
胖虎遛二狗
学习
Docker动手入门 | 大模型工程师必备技能 (🎉已完结)
docker是通用的跨平台解决方案,学习docker需要一些linux的基础
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/2b9027dfd3994ed080a50a1703d0faf0.png)
镜像:是一个二进制的文件,可以理解为一个模版,在这个模版上可以创建容器。镜像是环境和代码,是不能跑的东西
容器:实际是一个可以运行的东西,并且在镜像的基础上可以运行多个。
docker 命令 -h 或者 --help
可以查看docker命令的用法
1.Images
docker images # 列出镜像
docker image ls # 同样是列出镜像
docker search hello-world # 查找名为hello-world的镜像(在docker hub中查找)
docker pull hello-world #拉取一个名为hello-world的镜像
docker rmi hello-world # 删除一个名为hello-world的镜像
docker rmi -f hello-world # 强制删除一个名为hello-world的镜像
docker tag ee3 jiaoyidi/hello-world:1.0 把一个hello-world的镜像名改成自己喜欢的镜像名(带上了账户id和相同镜像名hello-world)(用于将一个镜像提交到公共仓库的时候用到)
jiaoyidi是docker的账号id,jiaoyidi/hello-world表示这个账户下的一个仓库,1,0就是版本号,修改完镜像名称,就可以把这个镜像推送到公共仓库中去
docker push jiaoyidi/hello-world:1.0 把刚才的镜像推送上去
别人搜索我推送的镜像:docker search jiaoyidi/hello-world
推送一个离线的镜像:docker save -o hw.tar jiaoyidi/hello-world # 是把镜像中的文件放到一个文件中,变成一个包,没有进行压缩。hw.tar是起的一个镜像文件名
tar只是打包
使用到tar.gz才是先打包再压缩
别人收到镜像文件,该如何使用:docker load -i hw.tar # 就是将镜像文件hw.tar输出出来
tag功能是给镜像打一个别名
docker history 镜像名 # 查看一个镜像以往被修改过的历史
docker inspect 镜像名 # 查看镜像中的内容
2.Container
docker ps # 看正在运行的容器
容器与宿主机隔离,宿主机访问容器的服务,服务是api的形式进行访问的,
0.0.0.0::5005->5000/tcp,这个代表宿主的机的50005端口可以访问到容器的5000端口
NAMES,如果不指定别名的话,会随机生成一个别名
docker ps -a # 把所有的服务全部列出来
docker stop e9c # 把e9c这个服务给停掉
docker start e9c # 把e9c这个服务给开启
docker restart e9c # 重启e9c这个服务,重启的意思应该是将关闭与开启的动作合在一起
docker rm e9c # 删除e9c这个容器(前提先要关闭这个容器),如果强制删除,则使用docker rm -f e9c(不推荐使用)
docker logs 容器名 # 查看容器的日志。
docker logs -f 容器名 # 跟踪日志输出,每次有访问,都会记录在容器日志
docker exec -it 291 bash # 进入291这个容器中,执行bash这个命令。-i表示交互性的 -t 表示终端 两个命令合在一起意思就是进入一个可交互的终端中去
解释参数中一个
-和两个
–的区别:
一个-
后面带的是一个字符,两个-
后面跟的是一个命令(如–rm),而不是像上面一样两个命令拼在一起的(-i和-t合在一起是-it)
如果临时要让宿主机与容器进行文件上的交互,使用下面指令:
docker cp ./hw.tar 291:/app/hw.tar # 将宿主机上的一个文件hw.tar拷贝到容器内部app下的hw.tar
docker cp 291:/app/hw.tar ./hw.tar # 将容器内部app下的hw.tar拷贝到宿主机上
docker stats # 查看docker占用的资源
docker networ # 查看网络,容器可以通过桥接访问宿主机的内容,宿主机为了保证容器是绝对干净的,所以不能访问容器的内容,如果要使用宿主机去访问容器内的东西,需要做端口映射,即0.0.0.0::5005->5000/tcp这样一个东西
docker run ee3 # 运行起来一个容器
docker run -d ee3 # 运行起来一个容器的同时不会占用当前的终端界面,d表示detach,分离的意思,可以理解为后台执行
docker run -it 4b1 bash # 启动一个容器4b1,生成一个可以交互的终端界面,进入之后给一个初始命令bash
docker run --rm -d 4b1 # 在后端执行一个容器之后如果这个容器被停止之后,会自动销毁,通过start会restart等都启动不了那个容器了
docker attach d1f # 进入到一个正在运行的终端
create这个命令不常用
kill 强制杀掉一个容器,也不常用
docker top 看下进程的占用,不常用
docker commit 09d 09d:1.0 # 把一个容器变成一个镜像,不建议这么做,原因是这么构建的镜像相当于是一个黑盒,有很高的不确定性。构建镜像的最好方法是从dockerfile去构建一个镜像,这样构建出的镜像别人可以复现出一个一模一样的镜像。
3.Dockerfile
自己构建一个镜像给别人用
FROM python:3.10-slim # 一个基础的镜像开始,如果这个镜像本地不存在的话,会从dockerhub上下载WORKDIR /app # 设置docker的工作路径,约定把所有的代码放在这个里面,这个路径是项目的根路径COPY . /app/ # 将宿主机上当前路径下所有的文件都拷贝到指定目录下RUN pip install flask # 执行命令,这个命令可以是任何linux上一个命令CMD ["python",“app.py”] # 以上操作执行完会构建出一个镜像,执行CMD会启动容器,是项目的入口
docker build -t d1 . # 根据当前目录下的一个Dockerfile文件去编译为一个镜像,.
表示当前目录,-t是为镜像设置一个标签,标签名为d1
ENTRYPOINT和CMD
① ENTRYPOINT ["echo",“1”]
② CMD [“echo”,"1"]
单独执行第1条命令,则会输出1 命令是docker run d1
如果命令 docker run d1 2,即2可以作为参数进行输入,输出是覆盖掉默认的1
单独执行第2条命令,则会输出1 命令是docker run d1
如果命令 docker run d1 2,即2不可以作为参数进行输入,不能覆盖掉默认的1,此时将报错
常见的用法是(合在一起)
ENTRYPOINT ["echo"]
CMD ["1"]
功能是以下:
docker run d1 # 默认打印1
docker run d1 2 # 将2做为参数输入进去,此时将打印2
COPY和ADD
COPY . /app/ # copy将dockerfile所在的文件夹下的内容复制到/app/下面
ADD docs.tar.gz /app/ # 可以实现和copy同样的功能,具备额外的两个功能:1、可以在网上下载文件(生产环境上基本不用),2、如果有tar包可以自动解压(这种功能也不用,因为它不显示解压过程,可读性差)
RUN tar -xvf # 如果想解压,直接写解压命令,可读性强
LABLE、EXPOSE和VOLUME
LABLE maintainer = "胖虎遛二狗" # 写过阅读dockerfile的人看的
EXPOSE 5000 # 把容器中的端口暴露出来
VOLUME ["./data"] # 声明容器中./data是用来存放数据的,可以与宿主机向连,也可以docker中的卷相连
上面的三个命令写不写都不对镜像构成影响,只是为了声明别人镜像中有这些信息
maintainer的命令已经不用了
user指定执行默认角色是root
shell改shell脚本
healthcheck
FROM python:3.10-slim WORKDIR /app LABLE maintainerEXPOSE 5000VOLUME ["./data"]COPY . /app/RUN pip install flaskCMD ["python",“app.py”]
构建上面这个镜像:docker build -t d4 .
运行上面的镜像:docker run -d -p 5001:5000 -v ./docs:/app/docs q4
-p:容器内部app.py使用的是5000端口,如果要让容器外也能访问容器内部的程序,需要做端口转发
,转发在命令中体现(5001:5000)
-v 是要将宿主的文件与容器内的文件进行交互,./docs:/app/docs表示将宿主机当前文件夹下docs与容器中/app/docs关联在起来,也就是这两个文件夹里面的文件的操作都是互通的,比如在宿主机上删除和创建、容器内部文件的删除与创建是同步的
q4 表示执行的是q4这个镜像
touch newfile.txt # 创建一个空文件
在实际开发中不建议把宿主机的文件与容器的文件绑定在一起
风险1:如果容器中某个文件是与宿主机关联的,宿主机上的文件被删除了,那么容器崩溃了,此时将会报错
风险2:绑定后运行效率低,不如利用容器自身的卷管理效率高
docker volume create vvv # 新创建一个卷,卷是docker自己维护的
docker volume ls # 列出所有的卷
docker run -d -v vvv:/app/docs q4 # 将容器中卷vvv与容器q4中的/app/docs绑定在一起
使用卷的方式可以实现容器之间的文件通信,但不适合实时通信。
卷的作用:
持久化存储: 卷用于保存容器中的数据,即使容器被删除,卷中的数据仍然保留。
数据共享: 卷可以在容器与主机之间共享数据,也可以在同一主机的多个容器之间共享数据。
虽然卷的主要用途不是通信,但可以通过共享卷实现容器之间的数据交换。
下面这两个命令可以实现上面图中表示的功能
docker cp # 把文件从容器拷贝到宿主机,把宿主机的文件拷贝到容器内
docker volume # 将宿主机的文件与容器中的文件绑定在一起;将卷与容器中的文件绑定在一起
docker run --mount type=volume,source=my-volume, target=/data image-xx # mount命令中type填卷的名字,source的值写源是什么,target的值写目标是什么,image-xx就是写docker run的镜像名字
docker run -v my-volume:/data image-xx
docker volume create v2 # 创建一个名为v2的卷
docker volume rm v2 #删除卷为v2的卷,删除是有条件的,就是和卷相关的镜像和容器必须都清理掉才能删除卷
卷中的数据是如何做数据备份的?
看下面的命令:
docker run --rm -it -v v1:/app/data1 -v ./docs:/app/data2 4b1 bash
这条命令将v1卷与容器中的data1进行绑定,将宿主机的./docs与容器中的data2进行绑定,将data1中的数据复制到data2中。–rm表示表示容器在退出后会自动删除。适合临时测试或调试场景,避免留下无用的容器。
数据备份(目标:将v1的数据备份到docs),将 data1 中的数据拷贝到 data2 中,会实现以下效果:
数据从卷 v1 复制到主机目录 ./docs。data1 对应的是 Docker 命名卷 v1 的内容。data2 对应的是主机上的目录 ./docs 的内容。将 data1 中的数据拷贝到 data2,相当于将 Docker 卷 v1 中的数据复制到主机目录 ./docs 中。
利用卷做数据备份的示例场景
假设:
主机上有一个目录 ./docs,里面包含一些文件。
主机上有一个命名卷 v1,里面也包含一些文件。
执行命令后:
1、容器启动,并挂载了 v1 和 ./docs。
2、进入容器的 Bash 终端后,可以访问 /app/data1 和 /app/data2 目录:
/app/data1 包含卷 v1 的内容。
/app/data2 包含主机目录 ./docs 的内容。
3、在容器中进行的任何修改(如创建、删除、修改文件)都会反映到主机上的卷或目录中。
4、退出容器后,容器会自动删除,但卷和目录中的数据会保留。
ARG和ENV
下面这两个命令有点云里雾里,还得再研究一下:
ARG APP_VER=1.0 # 主要用于构建容器过程中
ENV APP_ENV=1.0 # 主要用在容器运行过程中RUN echo “$APP_VER” # 打印APP_VER这个变量
RUN echo “$APP_ENV”
运行docker build -t q5 . 显示下面内容
运行docker run -it q5 bash,并执行env命令查看APP_ENV变量值
docker build --build-arg APP_VER=2.0 --build-arg APP_ENV=2.0 -t q6 .
可以通过变量APP_VER来将版本号传进去,但是上面中的命令不会改变APP_ENV
HEALTHCHECK
HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD curl--fail http://localhost:5000/ || exit 1
HEALTHCHECK是一个定时命令,会不断地测试这个容器会不断地运行,执行的命令是CMD curl–fail http://localhost:5000/,不断地调用5000端口,如果不能调用成功就会报错,–interval=10s是每隔10s进行测试一次,如果超时3s --timeout=3s --retries=3会重复请求3次
执行docker run -d -p 5005:5000 q7
可以查看容器的运行状态
4. Network(本节讲容器与容器之间的通信方案)
docker run -p 5001:5000 image-xxx # 将宿主机的5001端口映射到5000端口(容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P(大写) 或 -p (小写) 参数来指定端口映射)
如果不设置上面这条命令,那么容器外无法连接容器内部的服务,容器内可以连接宿主机网络。
为什么容器需要访问宿主机的网络: docker容器在运行过程中需要下载包,此时需要借助宿主机的网络。
容器与容器之间的通信是通过**桥接(bridge)**的方式进行的,container1和container2都连接上同一个网关(gateway)那么这两个container就是互通的。
使用一个例子介绍:
启动一个nginx服务,此时会带出来一个带有80端口的服务,
查看f89这个容器(docker inspect f89),可以看到网络连接方式是桥接,
网关地址:172.17.0.1
docker-compose这个工具可以用于管理多容器的问题