# 《Docker技术入门与实践》-第3版 读书笔记

# 第一部分:基础入门

# 第1章:初识Docker与容器

  1. Docker是基于Go语言实现的开源容器项目。

  2. Docker在开发和运维中的优势:

    • 更轻松的迁移和扩展。
    • 更简单的更新管理。
  3. Docker 与虚拟机相比:

    • Docker 容器启停更快。
    • Docker 容器对系统资源需求更少。
    • Docker使用仓库设计理念更方便用户获取分发和更新镜像,存储利用,增量更新。
    • Docker通过Dockerfile脚本支持灵活的自动化创建和部署机制,工作效率更高,程序更标准化。
  4. Docker与虚拟化:

  1. 小结:

    Docker基本概念,以及在云时代的优势。

# 第2章:核心概念与安装配置

  1. 核心概念:

    • Docker镜像(Image):类似虚拟机镜像,可以理解它为一个只读的模板。是创建Docker容器的基础。
    • Docker容器(Container):类似一个轻量级的沙箱(Sandbox),Docker利用容器来运行和隔离应用。容器是从镜像创建的应用运行实例。也可以把容器看作一个简易版的Linux系统环境以及运行在其中的应用程序打包而成的盒子。注意

    注意:镜像自身是只读。容器从镜像启动的时候,会在镜像最上层创建一个可写层。

    • Docker仓库(Repository):类似maven仓库,是Docker集中存放镜像文件的场所。

    注意:注册服务器的概念。

  1. 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...] OR docker 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=[:alias] 链接到其他容器
--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"
    

# 第5章:访问Docker仓库

# 第6章:Docker数据管理

# 第7章:端口映射与容器互联

# 第8章:使用Dockerfile创建镜像

# 第二部分:实践案例

# 第9章:操作系统

# 第10章:为镜像添加SSH服务

# 第11章:Web服务与应用

# 第12章:数据库应用

# 第13章:分布式处理与大数据平台

# 第14章:编辑开发

# 第15章:容器与云服务

# 第16章:容器实战思考

# 第三部分:进阶技能

# 第17章:核心实现技术

# 第18章:配置私有仓库

# 第19章:安全防护与配置

# 第20章:高级网络功能

# 第21章:libnetwork插件化网络功能

# 第四部分:开源项目

# 第22章:Etcd------高可用的键值数据库

# 第23章:Docker三剑客之Machine

# 第24章:Docker三剑客之Compose

# 第25章:Docker三剑客之Swarm

# 第26章:Mesos------优秀的集群资源调度平台

# 第27章:Kubernetes------生产级容器集群平台

# 第28章:其它相关项目

# 附录

# 附录A:常见问题总结

# 附录B:Docker命令查询

# 附录C:参考资源链接