文章目录
一. 原理与基础概念
docker 是开源的应用容器引擎, 通俗理解, 就像将货物通过集装箱托运一样, 将应用及环境依赖通过docker打包, 快速, 保证一致地作分发与部署.
Q:为什么要用docker ?
A:性能轻量,开销更低, 比传统的虚拟机更省钱.
docker运行在linux上, 严格讲它不是虚拟机, 而是一套文件隔离系统, 所以更轻量, 适合高密度部署, 也就更省钱.
docker-for-win10 就是运行在 WSL2 (Windows Subsystem for Linux) 之上的.
- 镜像, image, 业务应用及完整依赖的打包.
- 容器, container, 是镜像的实例化. 可 运行, 暂停, 删除. 镜像vs.容器 类比于 类vs.对象.
- 仓库, repository
二. 安装 docker
docker 可以分为 GUI前端, cli 命令行工具与引擎后端 等.
个人电脑都是桌面环境, 所以有个 GUI 前端会很好用, 我们装 docker Desktop, 包含了上句所有.
但 开发/部署 环境通常在服务器, 因为个人电脑的 内存/gpu 等比不上服务器.
docker-desktop-for-windows 11
旧一点的文章, 要有准备工作, 开启 windows 功能 | Containers 与 Hyper-V
, 服务 | server | 启动类型改自动
并重启.
2023.04 在 Windows 11 家庭中文版 实测不需要, docker 会引导提示, 并且用 WSL 2 作为后台, 不涉及 Hyper-V.
开始安装:
- 下载
Docker Desktop Installer.exe
, 约 650MB, 按照提示逐步安装. 它只能装在系统盘, 不能更改安装目录. 但使用中的容器存储位置是可以在GUI中设置更改的. - 启动 docker engine
内存/cpu 控制
- 内存. vmmem 进程在占用, todo
- cpu. todo.
c盘占用过大问题
能占用80G, 太夸张了. 主要是 .vhdx 硬盘映像文件. 默认存放在 C:\Users\yichu\AppData\Local\Docker\wsl
中, 导致C盘空间不足.
desktop-GUI 本身是能设置的, 在 齿轮图标 | Resources | Disk image location
中更改. 但是! 遇到永久卡顿, 见
docker-issu
退出 vmmemWSL 进程
安装 docker 后, 后续开机会自动启动其 backend 及 vmmemWSL 进程, 会占用10% 的 cpu, 怎么退出为电脑减负呢?
直接任务管理器结束进程会被拒绝, 需要到 “服务” 中关闭名为 “适用于 Linux 的 windows 子系统” 的服务即可.
docker-for-linux
ubuntu 与 redhat(centos, aliyun linux os) 安装包格式不同, 这个按官网教程来就行.
自己遇到的一个问题是, 2015年的 os 安装最新2023版 docker 会在运行容器时报错, 降级2018版才成功.
三. image 镜像
镜像的标识由 仓库服务/团体名/镜像名:标签
组成.
常用命令
- 拉取镜像
docker pull xx
- 生成镜像
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
如docker commit 3f38cb093cdb reg.docker.alibaba-inc.com/a/b:ver_0127
- 推送镜像
需要先登录, 如docker login --username=yichu.dyc reg.docker.alibaba-inc.com
,
再推送docker push reg.docker.alibaba-inc.com/a/b:ver_0127
image hub
叫仓库服务. 默认是中央仓库 hub.docker.com .
企业通常会有自己的私有仓库, 如 docker.xxcorp.com, 还会有 name/password 的权限控制.
列举我常用的流行镜像:
- https://hub.docker.com/_/ubuntu
- https://hub.docker.com/r/continuumio/anaconda3
- https://hub.docker.com/r/pytorch/pytorch
commit 制作镜像
在原始容器的基础上, 改动了环境与文件, 应用顺利运行, 就能用 commit 以此制作镜像作分发部署.
多次 commit 的镜像膨胀问题
按照时间先后推演一下.
- 原始镜像 1个G.
- 装了 cuda_10.2, commit A, 变成3个G
- 删除 cuda_10.2, 安装 cuda_11.3, 整个文件系统依旧三个G. 但 commit B, 发现是6个G.
- 继续迭代下去, 臃肿不堪.
原理是每次commit都是堆叠了一层, 并不只是最新的镜像.
怎么解决呢?
如果文件位置有规律, 就把需要的打包 data.tar. 从原始镜像开一个容器, 再把data.tar 移过去, 重新commit.
Dockerfile 制作镜像
优点有
- 白盒化, 镜像文件与 Dockerfile 就像 exe 程序与 cpp源码一样. 后者有完整的描述, 可以编译/构建得到前者.
- 镜像是分层的, 可以缓存, 复用.
一个完整例子:
FROM continuumio/anaconda3
LABEL author="yichu" description="构建于2023.04, 特性为 py3.9, jdk_11, anaconda科学计算, \
pytorch2.0(cuda11.7), transformers包, flask WEB相关, pyodps oss2阿里云相关"
ENV TZ=Asia/Shanghai
RUN pip install transformers shap torch torchvision torchaudio --trusted-host mirrors.aliyun.com -i http://mirrors.aliyun.com/pypi/simple/
RUN pip install pyodps oss2 --trusted-host mirrors.aliyun.com -i http://mirrors.aliyun.com/pypi/simple/
# 安装 java 及 常用shell 命令
RUN sed -i "s@http://\(deb\|security\).debian.org@https://mirrors.aliyun.com@g" /etc/apt/sources.list
RUN apt-get update
RUN apt-get install vim bsdmainutils default-jdk -y
# COPY <src> <dest>
COPY ./ /app/flask_demo
WORKDIR /app/flask_demo
CMD ["/bin/sh", "workspace"]
解读:
- FROM, 从基础镜像构建
- LABEL key=val , 是说明与注释
- RUN 执行命令, pip install 可以同时装多个包, --trusted-host 与 -i 是为了替换 pypi 境外的官方源, 加速下载
- COPY , 将本地文件复制到 docker 镜像中, 注意不能
../something
/something
这种写法, 只能在从当前目录视野下去操作,.
或./
指当前目录下所有文件. - CMD 分发后部署时才运行的命令
相关的 build, 打标, 推送命令为
docker build --tag py39_for_ai:v2023.04 .
# docker tag local-image:tagname new-repo:tagname
docker tag py39_for_ai:v2023.04 yichudu/py39_for_ai:v2023.04
docker push yichudu/py39_for_ai:v2023.04
四. 容器操作
创建容器
完整例子:
docker run -d --name=yichu_container --net=host -v /d/code-work:/yichu/d/code-work -it reg.docker.alibaba-inc.com/dii/dii_alios7u2_dev /bin/bash
解读如下:
-d
容器在后端运行
--name
容器名字
--net=host
使用本机网络
-v host_path:container_path
本地磁盘与容器文件系统的映射. windows盘符的d:
需要转换为/d/
.
-i
使用标准输入流作交互式操作.
-t
分配一个伪终端terminal.
reg.docker.alibaba-inc.com/dii/dii_alios7u2_dev
镜像地址
/bin/bash
容器的运行命令
高级特性:
容器内完成开发工作, gdb 调试等. 需要在 docker run
命令中加入--cap-add=SYS_PTRACE
参数.
管理
- 打印容器列表
docker ps -a
查看已有容器及其信息. - 终止
docker stop ${container_id}
- 启动
docker start ${container_id}
- 删除
docker rm ${container_id}
CLI 交互
容器后台启动后, 可以新开console窗口进入.
docker exec -it ${container_name} /bin/bash
用户名默认是 root.
五. 数据交换
容器内的文件与宿主机文件 双向挪腾.
docker cp [OPTIONS] container:src_path dest_path
docker cp [OPTIONS] dest_path container:src_path
六. 本地化
我们要把时区改为东八区, 制作镜像时, 可以加 ENV TZ=Asia/Shanghai
. 如果是用别人的镜像, 那么启动容器时可以加 -e TZ=Asia/Shanghai
.
参考
- 官网, docker for windows
- 他人blog, 如何在Docker容器内部使用gdb进行debug
- 官方doc, get-started