# 《Docker技术入门与实践》-第3版 读书笔记
# 第一部分:基础入门
# 第1章:初识Docker与容器
Docker是基于Go语言实现的开源容器项目。
Docker在开发和运维中的优势:
- 更轻松的迁移和扩展。
- 更简单的更新管理。
Docker 与虚拟机相比:
- Docker 容器启停更快。
- Docker 容器对系统资源需求更少。
- Docker使用仓库设计理念更方便用户获取分发和更新镜像,存储利用,增量更新。
- Docker通过Dockerfile脚本支持灵活的自动化创建和部署机制,工作效率更高,程序更标准化。
Docker与虚拟化:
小结:
Docker基本概念,以及在云时代的优势。
# 第2章:核心概念与安装配置
核心概念:
- Docker镜像(Image):类似虚拟机镜像,可以理解它为一个只读的模板。是创建Docker容器的基础。
- Docker容器(Container):类似一个轻量级的沙箱(Sandbox),Docker利用容器来运行和隔离应用。容器是从镜像创建的应用运行实例。也可以把容器看作一个简易版的Linux系统环境以及运行在其中的应用程序打包而成的盒子。注意
注意:镜像自身是只读。容器从镜像启动的时候,会在镜像最上层创建一个可写层。
- Docker仓库(Repository):类似maven仓库,是Docker集中存放镜像文件的场所。
注意:注册服务器的概念。
Docker引擎安装(https://www.docker.com/get-docker)
ubuntu环境
删除旧版本:
sudo apt-get remove docker docker-engine docker.io containerd runc #或 sudo apt autoremove docker-ce
方法一:
cat /proc/version #检查内核版本 也可用 uname -a sudo apt-get update # 更新软件包缓存 # 让Docker使用aufs存储.(16.04版本才需要执行) sudo apt-get install -y \ linux-image-extra-$(uname -r) \ linux-image-extra-virtual #安装apt-transport-https等软件包支持https协议的源 sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ software-properties-common #添加源的gpg密码 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -OK #确认导入指纹为"9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88"的GPG公钥 sudo apt-key fingerprint 0EBFCD88 #添加docker稳定版的官方软件源 sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable" #再次更新apt软件包缓存 sudo apt-get update #安装docker sudo apt-get install -y docker-ce docker-ce-cli containerd.io
- 方法二
#使用官方脚本安装 curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh #或 sudo curl -sSL https://get.docker.com/ | sh #想非root账号使用docker命令,把非root账号增加副群组docker sudo usermod -aG docker your-user
- 方法三
#下载 curl -fsSL https://download.docker.com/linux/ubuntu/dists/$(lsb_release -cs)/pool/stable/amd64/containerd.io_1.2.6-3_amd64.deb -o containerd.io_1.2.6-3_amd64.deb curl -fsSL https://download.docker.com/linux/ubuntu/dists/$(lsb_release -cs)/pool/stable/amd64/docker-ce_cli_18.09.8~3-0~ubuntu-$(lsb_release -cs)_amd64.deb -o docker-ce_cli_18.09.8~3-0~ubuntu-$(lsb_release -cs)_amd64.deb curl -fsSL https://download.docker.com/linux/ubuntu/dists/$(lsb_release -cs)/pool/stable/amd64/docker-ce_18.09.8~3-0~ubuntu-$(lsb_release -cs)_amd64.deb -o docker-ce_18.09.8~3-0~ubuntu-$(lsb_release -cs)_amd64.deb #安装 sudo dpkg -i containerd.io_1.2.6-3_amd64.deb sudo dpkg -i docker-ce_cli_18.09.8~3-0~ubuntu-$(lsb_release -cs)_amd64.deb sudo dpkg -i docker-ce_18.09.8~3-0~ubuntu-$(lsb_release -cs)_amd64.deb
CentOS环境
- 删除旧版本
sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
- 方法一:
#yum-utils provides the yum-config-manager utility #device-mapper-persistent-data and lvm2 are required by the devicemapper storage driver. sudo yum install -y yum-utils \ device-mapper-persistent-data \ lvm2 #添加Docker稳定版本的yum软件源 sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo #更新yum源 sudo yum update #安装docker sudo yum install docker-ce docker-ce-cli containerd.io #启动docker sudo systemctl start docker #设置docker跟随系统启动 sudo systemctl enable docker
配置Docker服务 把需要运行docker命令的用户加入docker用户组
sudo usermod -aG docker <USER_NAME>
开启debug模式
命令行启动:
dockerd -D -H tcp://127.0.0.1:2376
配置启动(/etc/docker/daemon.json):
{ "debug": true, "hosts": ["tcp://127.0.0.1:2376"] }
#linus下docker启动日志查看 journalctl-u docker.service #查看docker信息 docker info
# 第3章:使用Docker镜像
获取镜像
docker pull Name[:tag]
查看镜像信息
docker images OR docker image ls
搜寻镜像
docker search [option]keyword
-f, --filter filter:过滤输出内容;
--format string: 格式化输出内容;
--limit int: 限制输出结果个数,默认为25个;
--no-trunc: 不截断输出结果。
#搜索带nginx关键字的官方镜像 docker search --filter=is-official=true nginx #搜索带nginx关键字star大于等于4的镜像 docker search --filter=stars=4 nginx
删除和清理镜像
docker rmi IMAGE[IMAGE...]
ORdocker image rm IMAGE[IMAGE...]
IMAGE为标签或镜像ID,当有多个标签指向一个镜像ID时,删除一个标签并不会删除镜像,
- -f, -force:强制删除镜像;
- -no-prune:不要清理未带标签的父镜像。
docker image prume
清理镜像-a, -all:删除所有无用的镜像,不光是临时镜像
-filter filter: 只清理符合给定过滤器的镜像
-f,force: 强制删除镜像,而不进行提示确认
docker image prune -f
创建镜像
基于已有容器创建,基于本地模板导入,基于Dockerfile创建。
基于已有容器创建
docker [container] commit [OPTION]CONTAINER[REPOSITORY][:TAG]
-a, --author="":作者信息;
-c, --change=[]: 提交的时候执行Dockerfile指令,包括CMD|ENTRYPOINT|ENV|EXPOSE|LABEL|ONBUILD|USER|VOLUME|WORKDIR等
-m, --message="": 提交信息
-p, --pause=true: 提交时暂停容器运行。
docker commit -a "Mofar" -m "add a image" nginx 127.0.0.1:5000/nginx-test:0.0.1
基于本地模板导入
docker import [OPTIONS] file|URL-[REPOSITORY[:TAG]]
#eg: cat nginx.tar.gz | docker import - nginx:1.7.4 docker images
基于Dockerfile创建
- 创建Dockerfile文件
#eg: FROM debian:stretch-slim LABEL version="1.0" maintainer="soul0328@qq.com" RUN apt-get update && \ apt-get install -y python3 && \ apt-get clean && \ rm -rf /var/lib/apt/lists/*
创建镜像
docker build -t python:3 .
存出和载入镜像
存出镜像
docker save -o 保存文件名 镜像名
docker save -o ubuntu_18.04.tar ubuntu:18.04
载入镜像
docker load -i 文件名
docker load -i ubuntu_18.04.tar #或 docker load < ubuntu_18.04.tar
# 第4章:操作Docker容器
创建容器
介绍docker容器的create、start、run、wait、logs子命令
新建容器
docker create [OPTION] IMAGES:[TAG]
- create与容器运行模式相关的选项
选项 | 说明 |
---|---|
-a, --attach=[] | 是否绑定到标准输入、输出和错误 |
-d, --detach=true or false | 是否在后台运行容器,默认为否 |
--detach-keys="" | 从attach模式退出的快捷键 |
--entrypoint="" | 镜像存在入口命令时,覆盖为新的命令 |
--expose=[] | 指定容器会暴露出来的端口或端口范围 |
--group-add=[] | 运行容器的用户组 |
-i, --interactive=true or false | 保持标准输入打开,默认为false |
--ipc="" | 容器IPC命名空间,可以为其他容器或主机 |
--isolation="default" | 容器使用的隔离机制 |
--log-driver="json-file" | 指定容器的日志驱动类型,可以为json-file, syslog, journald, gelf, fluentd, awslogs, splunk, etwlogs, gcplogs, none. |
--log-opt=[] | 传递给日志驱动的选项 |
--net="bridge" | 指定容器网络模式,包括bridge,none,其他容器内网络,host的网络或某个现有网络等。 |
--net-alias=[] | 容器在网络中的别名 |
-p, --publish-all=true or false | 通过NAT机制将容器标记暴露的端口自动映射到本地主机的临时端口 |
-p, --publish=[] | 指定如何映射到本地主机端口,例如-p 11234-12234:1234-2234 |
--pid=host | 容器的PID命名空间 |
--restart="no" | 容器的重启策略,包括no,on-failure[:max-retry], always, unless-stopped等 |
--rm=true or false | 容器退出后是否自动删除,不能跟在-d同时使用 |
-t, tty=true or false | 是否分配一个伪终端,默认为false, |
--tmpfs=[] | 挂载临时文件系统到容器 |
-v or --volume[=[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]] | 挂载主机上的文件卷到容器内 |
--volume-driver="" | 挂载文件卷的驱动类型 |
--volume-from="" | 从其他容器挂载卷 |
-w, --workdir="" | 容器内的默认工作目录 |
- create命令与容器环境和配置相关的选项
选项 | 说明 |
---|---|
--add-host=[] | 在容器内添加一个主机名到ip地址的映射关系(通过/etc/hosts文件) |
--device=[] | 映射物理机上的设备到容器内 |
--dns-search=[] | DNS搜索域 |
--dns-opt=[] | 自定义的DNS选项 |
--dns=[] | 自定义的DNS服务器 |
-e, --env=[] | 指定容器内环境变量 |
--env-file=[] | 从文件中读取环境变量到容器内 |
-h, --hostname="" | 指定容器内主机名 |
--ip="" | 指定容器的IPv4地址 |
--ip6= | 指定容器的IPv6地址 |
--link=[ | 链接到其他容器 |
--link-local-ip=[] | 容器的本地链接地址列表 |
--mac-address="" | 指定容器的Mac地址 |
--name="" | 指定容器的名称 |
- create命令与容器资源限制和安全保护相关的选项
选项 | 说明 |
---|---|
--blkio-weight=10-1000 | 容器读写块设备的I/O性能权重,默认为0 |
--blkio-weight-device=[DEVICE_NAME:WEIGHT] | 指定各个块设备的I/O性能权重 |
--cpu-shares=0 | 允许容器使用CPU资源的相对权重,默认一个容器能用满一个核的CPU |
--cap-add=[] | 增加容器的Linux指定安全能力 |
--cap-drop=[] | 移除容器的Linux指定安全能力 |
--cgroup-parent="" | 容器cgroups限制的创建路径 |
--cidfile="" | 指定容器的进程ID号写到文件 |
--cpu-period=0 | 限制容器在CFS调度器下的CPU占用时间片 |
--cpuset-cpus="" | 限制容器能使用哪些CPU核心 |
--cpuset-mems="" | NUMA架构下使用哪些核心的内存 |
--cpu-quota=0 | 限制容器在CFS调度器下的CPU配额 |
--device-read-bps=[] | 挂载设备的读吞吐率(以bps为单位)限制 |
--device-write-bps=[] | 挂载设备的写吞吐率(以bps为单位)限制 |
--device-read-iops=[] | 挂载设备的读速率 (以每秒i/o次数为单位)限制 |
--device-write-iops=[] | 挂载设备的写速率(以每秒i/o次数为单位)限制 |
--health-cmd="" | 指定检查容器状态的命令 |
--health-interval=0s | 执行健康检查的时隔时间,单位可以为ms,s,m或h |
--health-retries=int | 健康检查失败重试次数,超过则认为不健康 |
--health-start-period=0s | 容器启动后进行健康检查的等待时间,单位可以为ms,s,m或h |
--health-timeout=0s | 健康检查的执行超时,单位可以为ms,s,m或h |
--no-healthcheck=true or false | 是否禁用健康检查 |
--init | 在容器中执行一个init进程,来负责响应信号和处理僵尸状态子进程 |
--kernel-memory="" | 限制容器使用内核的内存大小,单位可以是b,k,m或g |
-m, --memory="" | 限制容器内应用使用的内存,单位可以是b,k,m或g |
--memory-reservation="" | 当系统中内存过低时,容器会被强制限制内存到给定值,默认情况下等于内存限制值。 |
--memory-swap="LIMIT" | 限制容器使用内存和交换区的总大小 |
--oom-kill-desable=true or false | 内存耗尽时是否杀死容器 |
--oom-score-adj="" | 调整容器的内存耗尽参数 |
--pids-limit="" | 限制容器的pid个数 |
--privileged=true or false | 是否给容器高权限,这意味着容器内应用将不受权限的限制,一般不推荐 |
--read-only=true or false | 是否让容器内的文件系统只读 |
--security-opt=[] | 指定一些安全参数,包括权限,安全能力,apparmor等 |
--stop-signal=SIGTERM | 指定停止容器的系统信号 |
--shm-size="" | /dev/shm的大小 |
--sig-proxy=true or false | 是否代理收到的信号给应用,默认是true,不能代理SIGCHLD,SIGSTOP,SIGKILL信号 |
--memory-swappiness="0-100" | 调整容器的内存交换区参数 |
-u, --user="" | 指定在容器内执行命令的用户信息 |
--userns="" | 指定用户命令空间 |
--ulimit=[] | 通过ulimit来限制最大文件数,最大进程数等。 |
其它选项
- -l, --label=[]:以键值对方式指定容器的标签信息
- --label-file=[]: 从文件中读取标签信息。
启动容器
docker start XXX
docker ps
#查看所有容器 docker ps -a #启动nginx容器 docker start nginx #查看已启动的容器 docker ps
新建并启动容器
docker run XXX [command]
等价于docker create XXX & docker start XXX
docker run ubuntu:18.04 /bin/echo '傻嗨!'
docker run
的执行原理检查本地是否存在指定的image,不存在则从仓库下载
利用image创建一个container,并启动之。
分配一个文件系统给container,并在只读的image层外面挂载一层可读写层。
从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去。
从网桥的地址池分配一个IP地址给容器。
执行用户指定的应用程序;
执行完毕后容器被自动终止。
125:Docker daemon执行出错,例如指定了不支持的Docker命令参数;
126:所指定命令无法执行,例如权限出错;
127:容器内命令无法找到
命令执行后出错,会默认返回命令的退出错误码。
守护态运行
docker run -d XXX [COMMAND]
docker run -d centos /bin/bash -c "while true;do echo hello world; sheep 2; done"