Docker架构及其相关概念 ========================================================================================================================== 一、Docker基本概念 1、Docker Engine组件 Dockerd守护进程 RestAPI(程序通过此接口守护进程进行通信) Docker Client CLI使用Docker REST API通过脚本或者直接的命令与Docker守护进程通信。 2、Namespace 实现了资源隔离 Linxu内核提供的6种资源隔离系统调用: 主机名与域名 进程树:信号量、消息队列、共享内存 进程编号 网络设备、端口 根文件系统:根文件系统,挂载点(文件系统) 用户和用户组 根文件系统:特权根文件系统之上利用chroot的机制,模拟出一个个完整的虚拟根文件系统。 进程树:宿主机的进程树的一个子树负责给容器生成虚拟的进程树。 3、 Control Group 控制组实现了资源控制 子系统:从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子系统进行检测。 cgroups最初名称叫 process container,后来更名为control groups。 cgroups是Linux内核的一种机制。限制、记录任务组所使用的物理资源例如CPU、内存、IO等。cgroups是附加在程序上的一系列钩子, 通过程序运行对资源的调度触发相应的钩子以达到资源追踪和限制目的。 功能: 资源限制:例如设定应用运行时的内存的上限 优先级分配:控制任务运行的优先级 资源统计:统计系统资源的使用量。如CPU使用时长、内存用量 任务控制:对进程执行挂起、恢复操作 4、实现容器 利用Linux内核级支持的这些功能就可以实现资源隔离和资源控制进而实现容器的功能,软件开发人员需要手动编写组件调用系统的这些 功能,但这对应用容器显然是不友好的,因此就有了容器管理器辅助我们实现利用Linux内核的这些功能。 容器管理器的实现有:LXC(Linux Container)、Docker、Warden、lmctfy 5、Docker Object images 镜像是只读的,镜像启动为容器时,docker守护进程就在镜像的基础上进行启动为容器。此外当启动容器时会在镜像之上 附加一个读写层,读写操作都在这个读写层上进行。 container networks volumes plugins ========================================================================================================================== 二、LXC容器管理器 1、LXC(Linux Container)是一种操作系统级虚拟化。 2、使用LXC 1、安装 yum install lxc lxc-templates 2、命令工具 lxc-xxxx lxc-checkconfig # 检查需要使用的内核级的功能是否启用 lxc-info --name Centos7 # 查看容器信息 lxc-start --name Centos7 # 启动容器 lxc-start --name Centos7 -d # 后台运行 lxc-destroy # 删除容器 lxc-snapshot # 创建快照 3、lxc-templates rpm -ql lxc-templates /usr/share/lxc/templates/lxc-alpine # 启动不同操作系统的模板,这些模板都是bash脚本 /usr/share/lxc/templates/lxc-altlinux /usr/share/lxc/templates/lxc-archlinux /usr/share/lxc/templates/lxc-busybox /usr/share/lxc/templates/lxc-centos /usr/share/lxc/templates/lxc-cirros /usr/share/lxc/templates/lxc-debian /usr/share/lxc/templates/lxc-download /usr/share/lxc/templates/lxc-fedora /usr/share/lxc/templates/lxc-gentoo 4、创建一个容器 1、创建一个物理桥 cp -a ifcfg-eth0 ifcfg-virbr0 编辑ifcfg-eth0注释掉IP信息,并添加BRIDGE=virbr0 编辑ifcfg-virbr0修改TYPE="Bridge" NAME="virbr0" DEVICE="virbr0" 并保留IP地址 重启网络,查看网络接口是否正常,此时eth0相当于一个交换机 2、修改模板的yum源 修改/usr/share/lxc/templates/lxc-centos baseurl=https://mirrors.163.com/centos/7/os/x86_64/ 3、创建一个容器 lxc-create --name Centos7 -t /usr/share/lxc/templates/lxc-centos 4、lxc会随机生成root密码,保存在/var/lib/lxc/Centos7目录下,此目录下还会保存容器的所有相关文件 5、启动容器后查看网卡信息 5、使用LXC web界面 参考文档:http://lxc-webpanel.github.io/install.html 1、安装git clone https://github.com/lxc-webpanel/LXC-Web-Panel.git 2、安装python yum install python-flask ========================================================================================================================== 三、Docker registry 1、概念 一个registry中有多个repository,一个repository中有多个镜像,通常一个repository中有一种类型的镜像。 repository可分为“顶层仓库”和“用户仓库”,用户仓库名称格式为“用户名/仓库名”。 registry由repository和index组成。index是一个应用程序,用于维护用户账号,镜像检验,用户认证及检索功能。 2、标识镜像 每一个镜像都有一个标签 tag,标签通常标识镜像的版本,最新的版本通常用latest作为标签。 3、下载镜像 下载镜像时需要指明仓库名称和标签名称。 4、私有registry解决方案 docker-distribution vmware harbor 5、公有registry DockerHub 特性: 镜像仓库 自动构建镜像。基于Dockerfile文件自动构建 webhooks。 第三方registry 6、registry分类 Sponsor Registry:第三方的registry,供客户和Docker社区使用 Mirror Registry:第三方registry,只让客户使用 Vendor Registry:由发布Docker镜像的供应商提供 Private Registry:私有的registry 7、Registroy组成 Repository:多个版本组成的一个镜像仓库,一个registory可以有多个仓库。 Index:维护用户账号、镜像的校验及公共命令空间信息。 ========================================================================================================================== 四、Docker Image 1、Docker 镜像(Image),就相当于是一个 root 文件系统。除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了 一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。 2、分层构建 最底层为bootfs,其之上为rootfs bootfs:包括bootloader和kernel,容器启动之后会被卸载以节省资源 rootfs:表现为docker的根文件系统,rootfs由内核挂载为只读模式,之后通过联合挂载技术额外挂载一个可写层。 3、镜像生成途径 1、Dockerfile 2、基于容器制作 3、Docker Hub automated builds ========================================================================================================================== 五、aufs 1、aufs是一种Union File System,是将不同物理位置的目录合并mount到用一个目录下,联合挂载。 2、关于docker的分层镜像,除了aufs,docker还支持btrfs, devicemapper和vfs、overlayfs。 ========================================================================================================================== 六、Docker容器虚拟化网络 1、Linux内核原生支持2层虚拟网桥设备,用来构建一个虚拟交换机。 (桥接模式)。 桥接模式下通信,容易产生广播风暴。 2、OpenVSwitch是一个开源的软件定义网络的软件 3、Nat网络模型 4、网络叠加 使用这种所谓“包内之包”的技术安全地将一个网络隐藏在另一个 网络中,然后将网络区段进行迁移。某一个H1主机的报文 直接发送给宿主机的软交换机,其目标地址是另一台主机的虚拟机C2,当报文送到H1的网卡后,将在此报文上封装一层,源 地址是H1的网卡地址,目标地址是H2的网卡地址,报文到达H2后,将封装的首部拆封直到送达C2。 5、Docker网络 1、Docker网络有四种模式: 桥接模式 bridge docker守护进程创建一个网桥设备docker0,守护进程会创建一对对等接口,将其中一个接口设置为容器的eth0接口, 另一个接口放置在宿主机的命名空间中,从而将宿主机上的所有容器都连接到这个内部网络上。同时,守护进程还会 从网桥的私有地址空间中分配一个IP地址和子网给该容器。 主机模式 host 和宿主机共用网络名称空间,因此和宿主机具有相同的IP地址,之间将容器暴漏在公网环境中,存在一定的安全隐患。 需要将容器的端口映射给宿主机。此种模式更高效,因为没有额外的路由开销。 容器模式 docker_gwbridge 和某一个容器共用网络名称空间。 无网络模式 none 该模式关闭了容器的网络功能。 2、Docker默认使用的是桥接模式的网络,docker0是其创建的一个软交换机。安装bridge-utils工具,查看虚拟网卡信息。 docker0桥默认是nat桥。 3、joined container网络模式 容器之间共享名称空间。 ========================================================================================================================== 七、Docker存储卷 1、Docker镜像及写时复制 Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读层镜像并在镜像栈顶部添加一个读写层。 如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然 会存在,只是已经被读写层中该文件的副本所隐藏,此即“写时复制(COW)”机制。 2、存储卷 提供了独立于容器的数据管理机制。 讲宿主机上的某一目录或文件与容器内的某一目录或文件进行建立绑定关系。这样,容器内的进程在产生数据时可以直接写入宿主 机的文件系统之上。 3、存储卷类型 绑定挂载卷(Bind mount vloume):将宿主机和容器上的两个已经挂载卷做关联关系。使用-v选项进行指定 Docker管理卷(Managed vloume):用户指定,Docker daemon自动管理挂载。 ========================================================================================================================== 八、Docker系统资源限制及验证 1、默认情况下,一个容器没有任何资源限制,可以使用宿主机的所有资源。Docker提供了一个途径去控制容器使用宿主机的资源。 包括CPU和内存。这个功能包括Linux内核的capabilities特性。 2、在一个Linux主机上,如果主机探测没有足够的内存资源执行系统任务时,将抛出一个OOME异常以释放资源,并开始停止一些进 程,可能是任何进程。包括docker daemon在内,因此docker调整了OOM的优先级。 3、在启动容器时可以调整一个容器的oom_adj参数,以避免容器被kill掉。 4、 内存 -m,--memory= # 限制内存的使用。 --memory-swap # 限制使用交换分区的大小,设置此值必须先设置-m --oom-kill-disable # 禁止因为出发oome而kill掉容器 --memory-swappiness # 设置使用交换分区的倾向性,值可以是0-100 4、CPU --cpus= # 限制使用CPU核心数 --cpu-shares # 按比例进行分配CPU的使用。动态调整 --cup-period= # --cusset-cpus # 限制容器运行在那个CPU核心上 --cup-quota= # ==========================================================================================================================