Docker概念
1、Docker可以让开发者打包他们的引用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上。
2、容器是使用沙箱机制 ,相互隔离。
3、容器性能开销低。
Docker是一种容器技术 ,解决软件跨环境迁移的问题。
什么是镜像-Images?什么是容器-Container?什么是Dockerfile?
Image(镜像) :可以理解为虚拟机的快照 ,里面包含了你要部署的应用程序 以及它关联的所有库、软件。
通过镜像可以创建许多不同的Container容器,这些容器就行是一台台运行起来的虚拟机,里面包含了虚拟程序。每个容器独立运行,相互之间不影响。容器就是镜像的实例化。我们可以修改容器中的安装包啥的,然后保存这个容器成为一个新的镜像(在顶层叠加)。
如果学习Conda环境,这就很好理解了,我们每次构建一个项目都会使用Conda管理安装依赖包,实际上这个容器-Container就是一个对应Conda环境。
Dockerfile文件 就像是一个自动化脚本,它主要被用来创建镜像 。这个过程就好比我们在虚拟机中安装操作系统和软件一样 。只不过通过**Dockerfile**这个自动化脚本完成了。
Docker Demo
1、创建文件和文件夹
bash
# 1. 创建并进入目录
mkdir my-docker-demo
cd my-docker-demo
# 2. 生成一个简单的 Python 脚本
echo 'print("恭喜!你的 Docker 镜像运行成功了!")' > app.py
2、创建Dockerfile
bash
# 生成 Dockerfile 文件
cat > Dockerfile <<EOF
# 使用官方极其精简的 Python 镜像
FROM python:3.9-slim
# 设置容器内的工作目录
WORKDIR /app
# 把当前目录下的 app.py 复制进容器
COPY app.py .
# 容器启动时运行的命令
CMD ["python", "app.py"]
EOF
3、打包镜像
bash
docker build -t hello-demo .
由于上面的Dockerfile中用到了Python的镜像,因此需要去Docker仓库拉取到本地,之后才能继续构建镜像。
可能会报错,原因是镜像源,需要配置国内镜像源
(1)创建Docker配置文件
bash
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.1panel.live"
]
}
EOF
(2)重启Docker
bash
sudo systemctl daemon-reload
sudo systemctl restart docker
4、运行镜像
bash
docker run --rm hello-demo
根据hello-demo镜像创建一个新容器并启动它,当容器中任务完成后立即删除它。
如果你不加 --rm,Docker 的默认行为是: 容器跑完程序后,会变成 "停止状态 (Exited)" ,但它依然存在于你的硬盘上,占用空间,并保留着刚才运行的所有记录。
可以通过docker ps -a 查看所有容器 ,或者docker ps 查看所有活着的容器。
打印输出结果!
Docker常用命令
1、常用的查看镜像和容器命令
查看本地所有镜像:docker images
删除指定镜像:docker rmi <镜像ID或名称>
查看本地容器 :docker ps [-a] , 参数-a,如果不加-a,查看的是启动的容器,加上-a 表示查看的是所有的容器(启动与停止的都会显示)
查看容器的资源使用,比如CPU、内存等: docker stats
停止容器:docker stop <docker name>
启动停止的容器:docker start <docker name>
重启容器:docker restart <docker name>
删除容器:docker rm <docker name>
2、如果知道远端仓库的镜像地址,那么首先要将该镜像拉到本地才能使用
以下是拉取命令:
① 登录需要授权的镜像仓库(docker镜像服务器)
docker login -u <username> -p <password> <image_repo_link>
eg:docker login
② 退出登录的镜像仓库
docker logout <image_repo_link>
③ 从镜像仓库拉取镜像
docker pull <image_repo_link>/<image_name>/<image_tag>
3、镜像加载到本地后,如果要将镜像以容器的形式跑起来
常用的命令:
可以通过是否指定bash来决定容器 是运行在bash中,还是在后台运行。
场景一:交互式开发
创建并启动容器 (前台交互模式), 其中参数**-it** 表示前台交互模式 , --network host 表示容器直接共享宿主机网络,此时-p参数无效,容器内端口直接映射到宿主机端口。
bash
docker run -it \
[-v <宿主机路径>:<容器内路径>] \
[--network host]\
[-p 宿主端口:容器端口] \
[--name 容器名] \
[--gpus all] \
<镜像名(repo+tag)/镜像id> \
/bin/bash
-it含义:
-i表示保持标准输入打开,允许输入命令
-t表示分配一个伪终端,感觉是在用SSH登录一样,有命令行提示符组合使用
-it,启动容器后,直接跳进容器内部的终端里面。挂载(
-v):-v /home/user/project:/workspace作用:打通宿主机和容器的文件系统
工程价值:"代码在外面, 环境在里面"。可以在宿主机中用
VS Code写代码,代码实时同步到容器中运行,如果容器删了,数据还在。网络(
--network host与-p):
-p 8081:8080: 端口映射,把宿主机的8081端口映射到容器中的8888, 外界访问宿主机8081等于访问容器8888;
--network host:去隔离化,容器直接使用宿主机的网卡,容器监听8888, 宿主机就监听8888。GPU(
--guu all):使用这个参数,容器里面可以通过nvidia-smi看到显卡,并且使用Pytorch, 如果不使用, 那么容器里是看不到显卡的。
/bin/bash的作用:告诉容器启动后执行的第一个程序是Bash Shell
场景二:快照保存
命令行:
sudo docker commit my_sim_container my_sim_backup_image
场景:如果在容器中pip install很多包,或者修复了环境bug, 如果不保存,一旦删除容器,这些更改就会丢失。
作用:把当前容器的状态冻结,打包成一个新的镜像。
启动新的容器之前,使用**sudo lsof -i:8083**判断端口有没有被新的宿主机占用。
场景三:后台守护模式
bash
docker run -d \
[-v <宿主机路径>:<容器内路径>] \
[-p 宿主端口:容器端口] \
[--name 容器名] \
<镜像名>
创建并启动容器,通常用于部署服务,核心命令:docker run -d,-d表示容器启动后,不会占用当前终端,而是在后台默默运行。
进入已经启动的容器:docker exec -it <容器名> bash
启动一个远程shell: docker exec -it <容器ID> /bin/bash
Kubernetes 所做的就是将你的容器分发到一个集群(cluster)上运行。
bash
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors" :
[
"hub.atomgit.com",
"docker.m.daocloud.io",
"noohub.ru",
"huecker.io",
"dockerhub.timeweb.cloud",
"docker.rainbond.cc"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
Docker中的数据卷
bash
docker run --rm \
-v $(pwd)/train.py:/app/train.py \
-v $(pwd)/data:/app/data \
te-trainer:v1
挂载(-v)的核心原理 : 想象容器是一个封闭的房间。使用 -v 参数,就像是在房间墙上开了一个窗口 ,或者给房间插了一个U盘。
-
你在房间外(虚拟机)修改文件,房间里(容器)能立刻看到。
-
房间里跑出的实验结果(日志、模型权重),也能直接扔出窗外,保存在你的虚拟机硬盘上
-v $(pwd)/train.py:/app/train.py
冒号左边:虚拟机里的文件路径
冒号右边:容器中的文件路径