安装
https://docs.docker.com/engine/install/
生命周期
/var/lib/docker
docker
create # 创建容器(->created)没啥鸟用
start # 启动容器(created/stopped->start->running)
run # 运行(->start->running)
--name <容器名称> # 设置容器名
-d # 后台运行
-it # 分配终端
--rm # 执行完成后自行删除
-h <IP地址> # IP
-p <端口号> # 端口号
pause # 挂起容器(running->pause->paused)没啥鸟用
unpause # 挂起恢复(paused->unpause->running)没啥鸟用
restart # 重启容器(running->die->start->restart->running)
stop # 停止容器(running->die->stop->stopped)
kill # 停止容器(running->die->kill->stopped)
rm <容器编号1>[,容器编号2][,...] # 删除容器(created/stopped->destroy->deleted)
exec #执行容器
-it # 分配终端
ps #查看进程
-a # 所有进程
-q # 打印所有正在运行的容器id
容器的资源分配
CPU
docker run
-c 1024 # (CPU被吃满时分配1个核基于权重)
内存
docker run
-m 1024M # 分配1024M内存
--memory-swappiness 0 # 禁用内存交换
镜像管理
docker image ls # 查看本地镜像
docker rmi <镜像id> # 删除镜像
docekr push <镜像名> # 推送镜像到镜像仓库
docker tag <原镜像>[:TAG] <目标镜像名称>[:TAG]# 给镜像起别名
docker pull [镜像仓库地址]<镜像名>:<标签> # 拉取镜像
docker save -o <打包的包名> <镜像名>
docker logs <镜像id> # 查看镜像日志
docker inspect <容器id> |grep IP # 查看容器的ip地址
docker cp <宿主机目录> <容器id>:<容器目录> # 从宿主机目录传文件到docker中
docker commit [-m] [批注] <容器id> <生成后的镜像名>:<TAG> # 打包容器
镜像的层
镜像(image)是只读的,如果你修改镜像的内容,是在读写层(容器)中使用新的配置去覆盖下层的配置内容,而不是在原有配置的基础上进行修改,因此镜像只会越来越大,镜像的层数上限是128层。
读写层(用时分配,写时复制)
读写层用的时候就分配,不用不分配。写的时候从镜像层中复制到读写层以供修改。
存储驱动
overlay2是目前最主流的存储驱动,由Kernel发布,完美支持Ubuntu和CentOS,需要内核版本在3.18.0以上。可以通过以下命令查看当前docker的存储驱动等各种信息。
docker info
数据管理
数据卷特性(宿主机的磁盘划分持久化空间给容器使用)
数据卷是目录或文件,不能是未格式化的磁盘(block设备)
数据卷可以在容器间共享和重用
对数据卷的修改会立即生效
对数据卷的更新不会影响镜像
数据卷默认会一直存在即时容器被删除
创建数据卷
可以多次使用-v挂载多个数据卷
docker run -d -v <宿主机目录>:<容器目录>[:权限]
制作镜像
docker commit(缺陷:无法知晓内部细节,可能会有恶意程序)
dockerfile(写代码的方式构建镜像,十分流行)
FROM <容器名>:<TAG> # 引入一个基础镜像
LABEL <作者> <邮箱> # 作者信息,可以省略
ENV <key> <value> # 环境变量 TZ "Asia/Shanghai"
RUN <command> # 在容器中运行指令
ADD <dockerfile的目录及其子目录> <dest> # 从宿主机中复制文件到容器(如果是打包文件会自动解包)
COPY <dockerfile的目录及其子目录> <dest> # 跟上面ADD一样,但是不会自动解tar,gz之类的包
WORKDIR <path> # 指定工作目录
USER <user> # 后续操作指定使用user用户进行
VOLUME <容器目录> # 挂载数据卷,宿主机的/var/lib/docker/volumes/实例id/_data,权限只能rw,很少也不建议用
EXPOSE <port> # 对外声明端口
HEALTHCHECK [args] CMD <command> # 容器内部健康检查,很少用
CMD ["executable", "param1", "param2"] # 使用exec的方式执行,推荐
CMD command param1 param2 # 使用/bin/sh方式执行
CMD ["param1", "param2"] # 提供给ENTRYPOINT的默认参数
# 不会被docker run提供的参数覆盖;每个dockerfile只能有一个ENTRYPOINT
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
构建
docker build -t <容器名>:<TAG> <dockerfile文件位置>
ENTRYPOINT
vim entrypoint.sh
#!/bin/bash
exec "$@" # 保证ENTRYPOINT后的CMD能正常执行
dockerfile最佳实践
尽可能让变更少的镜像层放优先构建
二次构建时利用镜像的缓存特性会构建的更快
尽量少使用关键字,避免生成只读层
尽可能清理不必要的文件