Why and What
Docker vs VM
docker containers share the OS,VM 不同的OS。
docker 轻量,VM笨重
Docker on Different OSs
docker install 于 OS 之上。docker 可以 run 不同的 distribution,但是底层的kernel 要是一致的。比如 docker installed on Ubuntu 可以跑 Debian,但跑不了 Windows。至于,windows上安装的docker可以跑Ubuntu这样因为Windows在Linux VM上跑linux container。
commands
docker run # start a container
docker ps # list all running containers
docker ps -a # show all containers, even stopped or exited ones
docker stop (name or id)
docker rm (name or id) # remove stopped or exited container
docker inspect (name/id)
docker logs (name/id)
# 进阶
docker ps -q # only returns ids
docker stop $(docker ps -q) # stop all container
docker rm $(docker ps -qa) # rm all container, use this after above one
id 是不用打全的,只要能在当前的id中唯一就好
# related to image
docker images # list all available images
docker rmi (name/id) # 保证没有container基于此image
docker pull (nginx) # 只下不生成container
# 进阶
docker rmi $(docker images -q)
docker run ubuntu
# run an instance of ubuntu image and exits immediately
# docker ps and docker ps -a
# 会发现这个container已经是exited的状态了
和VM不同,container不是为了维持一个OS,而是去完成某项任务,一旦任务完成(或者crashed),就会exited。
# execute a command when running the container
docker run ubuntu sleep 5
如果想要对正在运行的containner进行操作
docker ps -a
docker exec (name/id) cat /etc/hosts
attach and detach when docker run
docker run (name/id) # run in the foreground 占用你当前的prompt
docker run -d (name/id) # 立马返回prompt 在background跑
docker attach (name/id) # attach back
一些解释
tag
tag, 用来指定版本 默认是latest
docker run redis:4.0 #
run stdin
docker run -it XXX
# i interactive
# t sudo terminal
run port mapping
docker run -p 80:5000 xxx/webapp
run volume mapping
不然,rm container后什么data都没了
docker run -v /host/data:/var/lib/mysql mysql
docker environment variable
docker run -e APP_COLOR=blue webapp
docker inspect webapp # 在env一栏可以看到环境变量
create your own image
最重要的就是dockfile,左边大写的是INSTRUCTION,右边其他的是ARGUMENT。
# dockerfile中的注释用#
# 但是和其他语言不一样的地方,必须在行首就用
# dockerfile must start with FROM
# based on some OS or image included OS
FROM Ubuntu
# run command on the base iamge
RUN apt-get update
RUN apt-get install python
RUN pip install flask
RUN pip install flask-mysql
# COPY files from local onto docker image
COPY . /opt/source-code
# specify a command that will be run when running as a container
ENTRYPOINT FLASK_APP=/opt/source-code/app.py flask run
docker build . 构建使用layered architecture,也就是每一行都是在原来的基础上新加的一层,docker history (image name)查看构建的过程。有cache的功能,也就是在后面add新的step,前面会被重用。
using both ENTRYPOINT and CMD
ENTRYPOINT ["sleep"]
CMD ["5"]
这样在外面用的时候 docker run sleeper 10 会override里面的CMD,注意这种情况下,俩个都必须使用json format。
networks
bridge,none,host。bridge是default,bridge以外的需要docker run Ubuntu --network=host
docker storage
/val/lib/docker
aufs
containers
image
volumes
使用不同dockerfile去build 不同image时,会(可能的话)重用之前的layers。
aufs 是一种 storage drivers。其他还有 overlayer 等等。
然后当docker run一个container时,前面build的layers都是read-only的,但docker会在他们上面建一个new writable layer (container layer)来store data like log files,当container被rm的时候,这个writable layer会消失。
COPY-ON-WRITE
如果对image layers中的file进行修改,修改后的结果会自行copy一份到container layer里。
volume
如果container被rm,那么container layer里的文件就会被删除,保存他们的方法就要用到volume。
# volume mounting
# created under /var/lib/docker/volumes/
docker volume create data_volume
# mount 外面:container内
docker run -v data_volume:/var/lib/mysql mysql
# 没有实现create volume也可以,docker会自动建一个
docker run -v data_volume2:/var/lib/mysql
# bind mounting
# 也可以mount其他地方,提供全路径
docker run -v /data/mysql:/val/lib/mysql mysql
# -v is obsolete, use --mount
docker run --mount type=bind,source=/data/mysql,target=/var/lib/mysql mysql
docker compose
docker registry
docker pull nginx, nginx其实是docker.io/nginx/nginx,第一个是registry,然后是user or account name,最后是image or repo name。docker.io是默认的,如果只给nginx,相当于nginx/nginx。
默认情况下,docker.io都是public,使用docker login private-registry.io去使用私有的。
docker engine
engine由三部分组成,从下到上:Docker Daemon,REST API,Docker CLI。
通过Namespace来做到containerization,分成Process ID,Network,InterProcess,Mount,Unix Timesharing等。
PID使得container直接使用host上的进程也不会乱。然后在docker内部维护一份不同的PID。
cgroup(control group)用于防止container占用过多或者全部的host资源,docker run --cpus=.5 --memory=100m ubuntu
docker 在 DL 中的使用
增加内存
docker run -it --network host --shm-size 8G xxx:v1
github issue,docker默认的shared memory不够大或者有其他问题,所以会出现无法使用num_worker >= 1的情况。把内存改大就好了。