《Docker 容器与云》 + 《Docker技术入门与实践》 1、Docker安装部署 2、docker命令 3、Docker原理及架构 4、docker daemon/client 5、镜像管理 6、容器管理 7、网络配置 8、Dockerfile 9、构建具有ssh服务的镜像 ========================================================================================================================== Docker安装部署 1、启动测试 # 启动docker systemctl start docker.service # 查看docker是都正常运行 docker info # 查看docker版本信息 docker info # 运行 docker run hello-world ========================================================================================================================== docker命令 格式:docker options command option: -H, --host list # 本地操作连接doker daemon的位置 子命令 run 格式:docker run [OPTIONS] IMAGE [COMMAND] [ARG...] -d=false|true # 后台运行docker容器 -t # 是为docker配一个伪终端,并绑定到标准输入 -i # 标准输入打开 --name NAME # 指定容器名称,如果未指定,则随机生成字符串UUID --log-driver="syslog|none" # 使用syslog进程记录日志或者禁用日志功能 --restart=always|on-failure:N # always表示无论退出码什么,都重新启动容器;on-failure:N ,表示退出码为非0时重启, N表示重启参数 -c # 用于给运行在宿主机中的所有进程分配CPU的shares值 -m # 用于限制容器中所有进程分配内存的总量B、K、M、G -v # 用于挂载一个逻辑卷。可以使用多个-v选项同时挂载多个逻辑卷。格式:[host_dir]:[container_dir]:[rw|ro] -p # 格式:hostPort:ContainerPort。通过将容器内的端口暴露给宿主机,达到通过宿主机的端口访问容器内的应用 hostPort:ContainerPort ip:hostPort:ContainerPort ip::ContainerPort # 映射到指定地址的任意端口 ip::ContainerPort/udp # 映射到指定地址的任意端口 Note:可以多次使用-p参数 -P {大写} # 暴露所有端口 --rm # 容器终止后删除容器 start stop restart pull [OPTIONS] NAME:[TAG @DIGEST] push images -a # 列出所有镜像 rm # 删除容器 -f # 强制 rmi # 删除镜像。删除镜像必须没有运维容器状态 -f # 强制 attach # 连接到正在运行的Container inspect # 查看进行和容器的详细信息。格式:docker inspect [OPTION] CONTAINER|IMAGE [CONTAINER|IMAGE] # 示例: docker inspect --format='{{.ID}}' centos # 查看指定字段的值 ps ps:List containers -a, --all:列出所有容器; --filter, -f:过滤器条件显示 name= status={stopped|running|paused} commit events history logs exec 格式:docker exec [OPTIONS] CONTAINER COMMAND [ARG...] 示例:docker exec -d web_nginx service nginx start ========================================================================================================================== 实践示例 1、下载所需要的镜像 # for I in ubuntu django haproxy redis;do docker pull $I;done 2、同一主机容器间的通信 --link # 可重复使用该选项 示例: --link master:master-redis # 后跟要通信的容器名称的列表 Note: 由于容器轻量化的设计,容器内没有文本编辑工具,所以在给容器内的应用提供配置文件时可以利用逻辑卷和宿主机共享数据。 ========================================================================================================================== Docker原理及架构 1、Docker通过 名称空间(namespace) 实现了资源隔离,通过 从 cgroups 实现了资源限制,通过写时复制 (copy-on-write) 实现了高效的文件操作。 2、名称空间 namespace 实现了资源隔离。 Linxu内核提供的6中资源隔离系统调用: 主机名与域名 信号量、消息队列、共享内存 进程编号 网络设备、端口 挂载点(文件系统) 用户和用户组 3、cgroups cgroups最初名称叫 process container,后来更名为control groups。 cgroups是Linux内核的一种机制。限制、记录任务组所使用的物理资源例如CPU、内存、IO等。cgroups是附加在程序上的一系列钩子,通过程序运行对资源 的调度触发相应的钩子以达到资源追踪和限制目的。 功能: 资源限制:例如设定应用运行时的内存的上限 优先级分配:控制任务运行的优先级 资源统计:统计系统资源的使用量。如CPU使用时长、内存用量 任务控制:对进程执行挂起、恢复操作 4、cgroup子系统 子系统:从groups的资源控制系统。每种系统控制一种资源。 cgroups的几种子系统:blkio、cpu、cpuacct、cpuset、devices、freezer、menory、per_event、ent_cls 子系统表现为文件系统,因此这个文件系统也需要挂载之后才能被系统所使用。使用mount -t cgroup命令查看。 限制某个PID进程的cpu使用配额:echo 18828 > /sys/fs/cgroup/cg1/tasks 限制CPU使用率:echo 20000 > /sys/fs/cgroup/cpu/cg1/cpt.cfs_quota_us 在Linux系统中,每一个从cgroups子系统的控制目录下,都有一个单独的docker目录,docker目录下又以每个容器名称为目录的目录,这个容器内的所有 进程和进程号都在此目录的控制组下。 cgroups的实现本质是给进程挂上钩子,当进程的运行涉及到某种资源时,就会触发钩子上所带的从groups子系统进行检测。 5、docker架构 docker的架构方式是server/client模式,docker clinet与docker daemon进行通信。docker server端是模块式的结构。 1、docker daemon:docker server端的主要接口,接收docker clinet端的请求。将docker clinet发来的请求翻译成对系统调用,从而完成对docker的管理 2、docker clinet:命令行工具docker, 3、镜像管理相关模块 distribution:负责与docker registry交互 registry: 与docker registry身份认证、镜像查找、镜像验证 image:负责与镜像元数据有关的存储、查找、镜像层的索引 reference: layer: 4、graphdriver:所有与镜像相关操作的最终执行者。 5、network:网络功能的实现由libnetwork完成,其抽象出一个网络模型 Contaier Network Model,CNM。 ========================================================================================================================== docker daemon/client 1、docker程序可以运行为 deaemon和client模式。 2、docker daemon初始化和启动过程 1、API server的配置及初始化 1、整理并解析用户指定的各项参数 2、创建PID文件 3、加载所需的server辅助配置,包括日志、是否允许远程访问、版本以及TLS认证消息 4、启动API server,server监听的位置是hosts的值 5、创建一个负责处理业务的daemon对象 6、对API server中的路由表进行初始化 7、设置一个channel 8、设置信号捕获,当docker daemon收到INT、TERM、QUIT信号时关闭docker daemon 9、API server与docker daemon绑定,开始接受client请求 10、docker daemon发送一个READY=1的信号,表示docker daemon正常运行 2、docker daemon创建及初始化 1、docker容器的配置信息:例如配置网络最大传输单元、检测网桥配置信息 2、系统支持及用户权限:root用户 3、配置daemon工作路径:/var/lib/docker/ 4、配置docker容器所需要的文件环境:在/var/lib/docker/目录下创建初始化一些重要的目录和文件 1、创建配置文件目录。/var/lib/docker/containers 2、配置graphdriver目录,用于docker容器镜像管理所需要的底层存储驱动。 3、配置镜像目录,用来存储所有镜像层。/var/lib/docker/image 4、创建volumes目录。/var/lib/docker/volumes 5、创建trust目录。用来处理可信镜像的授权和验证过程。 ========================================================================================================================== 镜像管理 1、镜像 只读的Docker容器模板:包括Docker容器运行所需要的文件系统及配置文件,称为rootfs Docker镜像是Docker容器的静态视角 2、启动过程 Docker容器启动过程中,将rootfs挂载为只读模式,当rootfs挂载完毕之后,利用union mount技术在只读的rootfs之上再挂载一个可读写层。当容器内有 内容发生变化时,将变化内容写到此可读写层上,并隐藏可读写层之下的旧版本。 3、Docker镜像特点 1、分层 当镜像的内容发生变化并提交为一个新镜像时,只是在镜像之上可读写层上作修改,并没有在可读写层之下直接作出修改,从用户的视角看到的是改变 之后的内容,而之前的旧版本内容被隐藏。分层可以达到在不同镜像之间共享镜像层的效果。 2、写时复制 copy-on-wirte,所有容器启动时将镜像以只读的方式挂载到一个挂载点,再在上面挂载一个可读写层,在Docker容器运行过程中有内容发生变化时,才 将变化的数据写到可读写层上。 3、内容寻址 计算每一层镜像的内容的哈希值,代替之前UUID作为每一个镜像层的唯一标识。 4、联合挂载 在同一个挂载点可以挂载多个文件系统,可以将挂载点原目录下的内容与挂载内容进行整合,最终可见的内容包括挂载内容和原目录内容。 4、相关概念 registry:用于保存docker镜像,包括docker镜像层次结构和镜像元数据。公有redisry Docker hub是docker官方维护的镜像仓库。docker hub中的仓库包括 私有仓库和共有仓库,私有仓库保存的是用户自己创建的镜像,公有仓库保存由docker官方维护的镜像。 repository:repostory是镜像的集合。registry是repository的集合。 manifest: image: layer: Dockerfile:用户使用docker build命令创建自己的镜像时需要指定的定义文件。 5、commit镜像 提交发生镜像变化部分的内容。 6、build镜像 构建新镜像。 docker build [OPTION] PATH | URL | - docker build - < Dockerfile # 从标准输入读入Dockerfile{镜像定义}文件 docker build gituhub.com/path/to/file # 从git仓库build一个镜像 7、镜像持久化及迁移 1、docker pull/docker push # 线上方式迁移 pull镜像过程: 根据用户输入的命令行参数,读取repository信息 2、docker save/docker load # 线下方式迁移 8、容器持久化及迁移 docker export docker import 9、镜像相关操作 1、为本地镜像添加标签 docker tag nginx:latest nginx:1.0 2、查看镜像的属性 docker inspect -f {{.XCCCXXX}} images_name 3、镜像搜索 docker search image_name 4、删除镜像 docker rmi image_name|image_id Note: 当有容器是从该镜像运行时,镜像无法被删除,-f 参数可强行删除 5、创建镜像 三种方法:基于已有镜像的容器创建; 基于本地模板导入创建; 基于Dockerfile创建; 1、commit 格式:docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] 选项: -a, --author string # 作者信息 -m, --message string # 提交信息 -p, --pause=true # 提交时暂停容器运行。默认的true 示例: docker commit -a "xuekaixin" -m "web_nginx" a729de35b56f test.image 2、基于本地模板导入 cat centos-7-x86_64.tar.gz | docker import - centos-7 6、保存或加载镜像 Note:将镜像保存为本地文件,或从本地文件导入为镜像。 保存镜像示例: docker save -o web_nginx.tar nginx 加载镜像示例: docker load -i web_nginx.tar 或者 docker load < web_nginx.tar 上传镜像示例: docker push user/testimage:lastest ========================================================================================================================== 容器管理 1、新建容器 docker create -it images_name Note:默认新建的容器处于停止状态,可用start启动容器 2、启动一个镜像为容器 1、docker run ...... 2、docker create docker start Note:当docker运行的bash进程结束,则docker自动终止运行。 3、守护状态的容器运行 -d # 使容器后台运行 4、终止容器 1、docker stop -t 10 # 首先向容器发送SIGTERM信号,等待一个-t指定的时间后再发送SIGKILL信号 2、docker kill # 直接强行终止容器的运行 5、进入容器 1、docker attach 2、docker exec 3、nsenter工具 # 获取容器的PID docker inspect -f "{{.State.Pid}}" test.centos # 连接进入容器 nsenter -t 8333 --mount --uts --ipc --net --pid 6、删除容器 格式:docker rm [OPTIONS] CONTAINER [CONTAINER...] 选项: -f -l, --link # 删除容器连接,但保留容器 -v # 删除容器挂载的数据卷 7、导出容器 docker export 21b0dddadcf8 > test.nginx.tar 8、导入容器 docker import ========================================================================================================================== 容器管理 Docker数据管理 1、启动容器时,使用-v选项并指明路径,即可在容器内创建文件或者目录 示例: 1、在容器创建一个目录: docker run -d --name test -h nginx -v /data centos 2、将物理机的root目录挂载到容器data目录,还可以挂载时指定权限,比如-v /root:/data:rw: docker run -d --name test2 -h nginx -v /root:/data nginx 3、查看目录数据卷的映射: docker inspect -f {{.Volumes}} CONTAINER_NAME docker1.8版本之后:docker inspect -f {{.Mounts}} centos-1 或者:docker inspect centos-1 | grep -C 20 "Mounts" 2、数据卷容器 --volumes-from CONTAINER_ID 3、数据管理 1、数据卷:Data volumes 理解: 可供容器使用的目录。containers使用数据卷类似于挂载某个目录到容器内。数据卷的生命周期独立于容器。 特点: 多个容器可以共享数据卷 对数据卷的修改可以立刻生效 数据卷会永久存在,除非手动删除数据卷 删除数据卷: 在删除容器的时候,可以指定-v选项同时删除容器相关的数据卷 2、数据卷容器:Data volumes containers 理解: 数据卷容器事实上也是一个正常的容器,只是其功能是专门提供数据的容器,数据卷容器并不需要保持运行状态。 还可以从已经挂载的数据卷容器的容器上关联并挂载其上的数据卷。 创建数据卷容器: docker run -d -v /dbcontainer --name dbcontainer centos 挂载使用数据卷容器: --volumes-from 数据卷名称 # 将数据卷容器dbcontainer挂载到centos-2容器上 docker run -d --volumes-from dbcontainer --name centos-2 centos # 查看数据卷挂载信息 docker inspect -f {{.Mounts}} centos-2 删除数据卷容器: 前提:如果数据卷容器被其他容器所挂载,则数据卷容器不能被删除,在删除最后一个挂载了数据卷容器的容器时, 使用docker rm -v选项删除,即可删除数据卷。 删除数据卷容器,但并不会删除数据卷。 3、数据卷的备份、恢复、迁移 备份示例: # 创建数据卷容器 docker run -d -i -t -v /data --name db centos /bin/bash # 新启动其他容器挂载数据卷容器的数据卷 docker run -d -i -t --volumes-from db --name centos-0 centos /bin/bash # 目的:是将数据卷容器中的data目录进行备份,进而保存到本地 方法:启动一个新容器并在这个新容器上挂载数据卷容器的数据卷,同时将本地的一个目录映射到 新启动的这个容器上,最后在这个容器上执行备份命令,将挂载之后的数据卷目录内文件打 包备份到容器内被映射到本地的那个目录内,就此完成数据卷的备份工作。 docker run --volumes-from db -v $(pwd):/backup --name backup centos tar cvf /backup/backup.tar /db 注意: 在备份的时候,可能会遇到权限问题,此时需要关闭SElinux。 恢复示例: # 创建一个带有空数据卷的容器 docker run -v /data1 --name db1 centos /bin/bash ========================================================================================================================== 网络配置 1、容器互联容器间的通信 1、端口映射 2、链接的方式 --link name:alias # name是要链接的容器的名称,alias是这个连接的别名 示例: docker run -i -t -d --name test2 --link test1:test1 centos /bin/bash ========================================================================================================================== Dockerfile 1、Dockerfile是一个文本文件,用来自定义镜像。 2、语法格式 1、"#" 为注释内容 3、Dockerfile文件组成 基础镜像信息 维护者信息 镜像操作指令 容器启动时执行的指令 4、文件格式 FROM centos MAINTAINER docker_user docker_user@mail.com # 镜像的操作指令 RUN ...... # 镜像启动时执行的指令 CMD ..... 5、Dockerfile指令 1、FROM FROM image_name|image_name:tag。第一条指令必须为FROM 2、MAINTAINER MAINTAINER name 3、RUN 格式: RUN command RUN ["/bin/bash","-c","echo hello"] 4、CMD 格式: CMD ["/bin/bash","-c","echo hello"] CMD command param1 param2 # 默认在/bin/sh中执行命令 每个Dockerfile都只能有一条CMD命令 5、EXPOSE 格式: EXPOSE [port ...] 指定Docker服务器暴露的端口号 6、ENV 格式: ENV 指定环境变量,会被后续的RUN指令使用 7、ADD 格式: ADD 复制文件到指定容器内的位置。src可以是Dockerfile所在目录下的一个文件或者目录,也可以是一个URL,也可以是一个tar文件,tar文件将自动解压缩 8、COPY 格式: CPOY 和ADD类似,但COPY会在目标目录不存在时自动创建 9、ENTRTPOINT 格式: ENTRTPOINT [["/bin/bash","-c","echo hello"]] ENTRTPOINT command param1 param2 # 在shell中执行 不会被docker run指令的命令覆盖 10、VOLUME 格式: VOLUME ["/data"] 创建一个挂载点 11、USER 格式: USER daemon 指定运行容器的用户名或UID 12、WORKDIR 格式: WORKDIR /path/to/workdir 为后续的RUN、CMD等指令配置工作目录 13、ONBUILD 示例: ONBUILD ADD . /app/src 指定创建其他镜像将当前镜像指定为基础镜像时要执行的指令 示例: RUN buildDeps='gcc libc6-dev make' \ && apt-get update \ && apt-get install -y $buildDeps \ && wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \ && mkdir -p /usr/src/redis \ && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \ && make -C /usr/src/redis \ && make -C /usr/src/redis install \ && rm -rf /var/lib/apt/lists/* \ && rm redis.tar.gz \ && rm -r /usr/src/redis \ && apt-get purge -y --auto-remove $buildDeps 6、构建镜像 ========================================================================================================================== 构建具有ssh服务的镜像 docker run -i -t --name test.sshd centos /bin/bash yum install openssh-server net-tools mkdir /var/run/sshd passwd root ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key ssh-keygen -t rsa -f /etc/ssh/ssh_host_ecdsa_key ssh-keygen -t rsa -f /etc/ssh/ssh_host_ed25519_key /usr/sbin/sshd -D & vim run.sh #!/bin/bash /usr/sbin/sshd -D exit docker commit sshd.test sshd.centos docker run -p 1024:22 -d sshd.centos /run.sh ========================================================================================================================== 总分总 搜索引擎,大概了解,建立一个大概的了解 以官方文档为主,各个击破 再次总结