• Docker进阶与实战上


    华为Docker实践小组集大成之作,此文主要是摘录笔记,分为上下两部分,陆续更新,欢迎交流

    简介

    概念澄清

    DockerLXC基础上做了什么工作

    LXC含义

    • LXC用户态工具
    • Linux Container内核容器技术简称

    通常指第二种,其特性为

    • 跨主机部署
    • 以应用为中心
    • 自动构建
    • 版本管理
    • 组件重用
    • 共享
    • 工具生态链

    Docker容器与虚拟机

    • 虚拟机:是用来进行硬件资源划分的完美解决方案,利用硬件虚拟化技术,通过一个hypervisor层来实现对资源的彻底隔离;
    • 容器:是操作系统级别的虚拟化,利用内核的CgroupNamespace特性,通过软件实现虚拟化,仅仅是进程本身就可以与其他进程隔离开,不需要任何辅助

    对比虚拟机的总结

    特性 容器 虚拟机
    启动 秒级 分钟级
    硬盘使用 一般为MB 一般为GB
    性能 接近原生 弱于
    系统支持量 单机支持上千个容器 一般几十个

    关于容器技术

    容器技术的前世今生

    关于容器技术

    容器技术主要包括CgroupNamespace

    • Namespace 又称命名空间,主要做访问隔离。其原理是针对一类资源进行抽象,并将其封装在一起提供给一个容器使用,对这类资源每个容器都有自己的抽象并且彼此不可见,所以就可以做到访问隔离。
    • Cgroupcontrol group 的简称,又称为控制组,主要是做资源控制。其原理是将一组进程放在一个控制组里,通过给这个控制组分配指定的可用资源,达到控制这一组进程可用资源的目的。

    一分钟理解容器

    容器的组成

    容器 = cgroup + namespace + rootfs + 容器引擎(用户态工具)

    • Cgroup:资源控制
    • Namespace: 访问隔离
    • rootfs: 文件系统
    • 容器引擎:生命周期控制

    容器的创建原理

    代码一:

    pid = clone(fun, stack, flags, clone_arg);
    (flags: CLONE_NEWPID | CLONE_NEWNS |
    CLONE_NEWUSER | CLONE_NEWNET |
    CLONE_NEWIPC | CLONE_NEWUTS |
    ...)
    

    通过clone系统调用,并传入各个Namespace对应的clone flag,创建了一个新的子进程,该进程拥有自己的pidmountusernetipcuts namespace

    代码二:

    echo $pid > /sys/fs/cgroup/cpu/tasks
    echo $pid > /sys/fs/cgroup/cpuset/tasks
    echo $pid > /sys/fs/cgroup/blkio/tasks
    echo $pid > /sys/fs/cgroup/memory/tasks
    echo $pid > /sys/fs/cgroup/devices/tasks
    echo $pid > /sys/fs/cgroup/freezer/tasks
    

    将代码一中产生的进程pid写入各个Cgroup子系统中,这样该进程就可以受到相应的Cgroup子系统的控制

    代码三:

    fun()
    {
      ...
      pivot_root("path_of_rootfs/", path);
      ...
      exec("/bin/bash");
      ...
    }
    

    fun函数由上面生成的新进程执行,在fun函数中,通过pivot_root系统调用,使进程进入一个新的rootfs,之后通过exec系统调用,在新的NamespaceCgrouprootfs中执行"/bin/bash"程序

    Cgroup介绍

    Cgroup是什么

    Cgroupcontrol group的简写,属于Linux内核提供的一个特性,用于限制和隔离一组进程对系统资源的使用,也就是做资源的Qos,这些资源主要包括CPU、内存、block I/O和网络带宽。

    Cgroup中实现的子系统及其作用如下:

    • devices:设备权限控制
    • cpuset:分配指定的CPU和内存节点
    • cpu:控制CPU占用率
    • cpuacct:统计CPU使用情况
    • memory:限制内存的使用上限
    • freezer:冻结(暂停)Cgroup中的进程
    • net_cls:配合tctraffic controller)限制网络带宽
    • net_piro:设置进程的网络流量优先级
    • huge_tlb:限制HugeTLB的使用
    • perf_event:允许Perf工具基于Cgroup分组做性能监测

    Namespace 介绍

    Namespace是什么

    Namespace是将内核的全局资源做封装,使得每个Namespace都有一份独立的资源,因此不同的进程在各自的Namespace内对同一资源的使用不会互相干扰

    目前Linux内核总共实现了6种Namespace

    • IPC:隔离System V IPCPOSIX消息队列
    • Network:隔离网络资源
    • Mount:隔离文件挂在系统
    • PID:隔离进程ID
    • UTS:隔离主机名和域名
    • User:隔离用户ID和组ID

    理解Docker镜像

    Docker image概念介绍

    Docker image是用来启动容器的只读模板,是容器启动所需要的rootfs,类似于虚拟机所使用的镜像。

    Docker镜像的表示方法
    Remote-dockerhub.com/namespace/bar:latest

    • Remote-dockerhub.com: Remote image hub,集中存储镜像的Web服务器地址(若缺少,则使用默认的镜像库,即Docker官方镜像库)
    • namespace: Namespace,类似于Github中的命名空间,是一个用户或组织中所有镜像的集合
    • bar: Repository,类似于Github仓库,一个仓库可以有很多个镜像,不同镜像通过tag来区分
    • latest: Tag,类似于Git仓库中的tag,一般用来区分同一镜像的不同版本
    • Layer:镜像有一系列层组成,每层都用64位的十六进制,类似于Git仓库中的commit
    • Image ID:镜像最上层的layer ID就是该镜像的IDRepo:tag提供了易于人类识别的名字,而ID便于脚本处理、操作镜像

    使用Docker镜像

    Docker内嵌了一系列命令制作、管理、上传、下载镜像,可以调用REST APIDocker daemon发送相关命令,也可以使用client端提供CLI命令完成操作。

    列出本机的镜像

    docker images

    Build:创建镜像

    • 直接下载 docker pull busybox
    • 导入镜像
      • docker save -o busybox.tar busybox 导出busyboxbusybox.tar
      • docker load -i busybox.tar 导入该镜像
    • 制作新镜像 docker import 用于导入根文件系统的归档,并将之变成Docker镜像。常用于制作Docker基础镜像,与此相比,docker export则是把一个镜像导出为根文件系统的归档

    Ship:传输一个镜像

    镜像传输是连接开发和部署的桥梁。可以使用Docker镜像仓库做中转传输,还可以使用docker export/docker save生成的tar包来实现,或者使用Docker镜像的模板文件Dockerfile做间接传输。

    Run:以image为模板启动一个容器

    启动容器时,使用docker run命令

    • 命令间逻辑不一致,docker ps列出容器,docker images列出镜像
    • docker inspect 查看容器和镜像的详细信息

    Docker image的组织结构

    Docker image包含着数据及必要的元数据。数据由一层层的image layer组成,元数据则是一些JSON文件,用来描述数据(image layer)之间的关系以及容器的一些配置信息。

    写时复制

    当父进程fork子进程时,内核并没有为子进程分配内存(当然基本的进程控制块、堆栈还是需要的),而是让父子进程共享内存。当两者之一修改共享内存时,会触发一次缺页异常导致真正的内存分配。这样既加速了子进程的创建速度,又减少了内存的消耗。

    仓库

    什么是仓库

    仓库(repository)是用来集中存储Docker镜像,支持镜像分发和更新

    仓库的组成

    仓库的名字通常是由两部分组成,中间以斜线分开,斜线之前是用户名,斜线之后是镜像名。

    仓库镜像

    仓库下面包含一组镜像,镜像之间用标签(tag)区分,一个完整的镜像路径通常由服务器地址、仓库名称和标签组成

    registry.hub.docker.com/official/ubuntu:14.04

    它代表Docker Hub上的Ubuntu官方镜像,发行版本是14.04

    • docker push localhost:5000/official/ubuntu:14.04 向本地私有仓库上传镜像,如果不写服务器地址默认上传到官方Docker Hub
    • docker pull ubuntu:14.04 下载镜像,不写服务器地址默认从官方Docker Hub下载
    • docker search localhost:5000/ubuntu 查询镜像

    再看Docker Hub

    Docker Hub优点

    • 为开发者提供海量的Docker镜像,供免费下载学习和使用
    • 拥有完善的账户管理系统,为用户提供付费扩容
    • 服务器采用分布式部署,支持负载均衡
    • 支持镜像上传、下载、查询、删除及属性设置等多种操作
    • 支持在线编译镜像
    • 后端采用分布式存储,可容灾备份
    • 其核心是Docker distribution,在开源社区上设计维护,会不断更新和完善
    • 提供企业版Docker Hub,为企业级用户提供一站式解决方案

    账户管理系统

    • 用户可以编辑自己的注册信息,如密码邮箱等
    • 创建和删除用户下的镜像
    • 收费用户可以创建和设置私有镜像
    • 创建和维护组织,添加组员
    • 用户之间可以互相关注

    仓库服务

    Registry功能和架构

    Registry旨在实现镜像的创建、存储、分发和更新等功能

    • 镜像存储 镜像数据存储在Registry后端,与本地镜像存储方式类似,它也分隔成多个镜像层,放置在各自的目录中,保存成tar格式。还保留了清单文件(manifest)和镜像签名文件(signature)等
    • 镜像创建、分发和更新 本地用户和Registry之间通过Registry API传输镜像。Registry API 即一系列HTTP/HTTPS请求,用来发送用户请求到Registry,并接收Registry响应,请求响应中包含了镜像数据的交互

    Registry特点

    • 快速上传和下载镜像
    • 设计方案新颖且高性能
    • 部署方便
    • 有详细完整的Registry API说明文档
    • 后端支持多种分布式云存储方案(s3、azure)和本地文件系统等,接口以插件方式存在,易于配置
    • 清单文件(Manifest)作为元数据完整的记录镜像信息
    • Webhook方式实现通知系统
    • 实现了本地的TLS,支持HTTPS安全访问
    • 有可配置的认证模块
    • 有健康检查模块
    • 管理镜像的清单文件和摘要文件格式清晰,更清楚地为镜像打标签
    • 拥有完善的镜像缓存机制,镜像下载更加快捷

    Registry API

    API描述:Registry API遵循REST设计标准,用于RegistryDocker Engine之间的通信,实现Registry镜像分发,是Docker Registry的重要组成部分

    API传输的对象主要包括镜像layer的块数据(blob)和表单(Manifests

    ManifestJSON格式的文件,记录镜像的元数据信息,并兼容V1版本镜像信息

    {
      "name": <name>,
      "tag": <tag>,
      "fsLayers": [
        {
    	  "blobSum": <tarsum>
    	},
    	...
      ],
      "history": [...],
      "signatures": [...]
    }
    

    鉴权机制

    鉴权机制是Registry V2版本之后新增的功能,目的是校验用户请求权限。校验和控制访问权限的任务是由Docker EngineRegistryAuth Service 协作完成

    部署私有仓库

    运行私有仓库

    Docker私有服务(private registry)用来建设私有仓库、管理私有Docker镜像。

    部署私有服务的有点:

    • 可独立开发和运维私有仓库
    • 节省带宽资源
    • 有独立的账户管理系统
    • 增加了定制化功能

    搭建私有仓库的前提是部署Docker Private Registry。命令如下
    docker run -d --hostname localhost --name registry-v2 -v /opt/data/distribution:/var/lib/registry/docker/registry/v2 -p 5000:5000 registry:2.0

    构建反向代理

    在实际使用中,暴露主机端口的方法是不安全的,如果Registry没有配置访问代理,任何用户都可以直接通过端口访问,因此,设计时需要为其加上HTTPS反向代理。
    该方式会用代理服务器来接受用户的HTTPS请求,然后将请求转发给内部网络上的Registry服务器,并将Registry响应结果返回给用户。

    Index及仓库高级功能

    Index作用和组成

    Index作用:

    • 管理Docker Private Hub注册用户,认证用户访问权限
    • 保存记录和更新用户信息,以及token等校验信息
    • Docker元数据(metadata)存储
    • 记录用户操作镜像的历史数据
    • 提供操作界面Web UI,用户可以方便的访问和更新资源

    Index主要由控制单元、鉴权模块、数据库、健康检查和日志系统组成

    Docker网络

    Docker网络现状

    Libnetwork提出新的容器网络模型(Container Network Model,简称CNM),定义了标准的API用于为容器配置网络,其底层可以适配各种网络驱动。

    CNM三个重要概念

    • 沙盒 是一个隔离的网络运行环境,保存了容器网络栈的配置,包括了对网络接口、路由表和DNS配置的管理。
    • Endpoint 将沙盒加入一个网络,Endpoint的实现可以是一对veth pair或者OVS内部端口,当前的Libnetwork使用的是veth pair
    • 网络 网络包括一组能互相通信的Endpoint。网络实现可以是Linux bridgevlan

    CNM的概念角度讲,Libnetwork的出现使得Docker具备了跨主机多子网的能力,同一个子网内的不同容器可以运行在不同主机上

    Libnetwork五种驱动(driver

    • bridge Docker默认的容器网络驱动
    • host 容器于主机共享同一Network Namespace,共享同一套网络协议栈、路由表及iptables规则等,容器和主机看到的是相同的网络视图
    • null 容器内网络配置为空,需要用户手动为容器配置网络接口及路由等
    • remote Docker网络插件的实现,Remote driver 使得Libnetwork可以通过HTTP RESTful API对接第三方的网络方案,
      类似SocketPlaneSDN方案只要实现了约定的HTTP URL处理函数及底层的网络接口配置方法,就可以替换Docker原生的网络实现
    • overlay Docker原生的跨主机多子网网络方案

    基本网络配置

    Docker网络初探

    Docker五种容器网络模式

    • none 不为容器配置任何网络功能
    • container 与另一个运行中的容器共享Network Namespace,共享相同的网络视图
    • host 与主机共享Root Network Namespace,容器有完整的权限可以操纵主机的协议栈、路由表和防火墙等,所以被认为是不安全的
    • bridge Docker设计的NAT网络模型
    • overlay Docker原生的跨主机多子网模型

    网络解决方案进阶

    • Weave
    • Flannel
    • SocketPlane

    容器卷管理

    Docker卷管理基础

    增加新数据卷

    docker run -d -v /tmp/data --name busyboxtest busybox
    其中-v参数会在容器的/tmp/data目录下创建一个新的数据卷,用户可以通过docker inspect 命令查看数据卷所在主机中的位置

    将主机目录挂载为数据卷

    -v参数除了可以用于创建数据卷外,还可以用来将Docker daemon所在主机上的文件或文件夹挂载在容器中
    docker run -d -v /host/data:/data --name busyboxtest busybox
    上述命令是将主机的/host/data目录挂载在容器的/data目录

    还可以只读的方式挂载

    docker run -d -v /host/data:/data:ro --name busyboxtest busybox

    如果容器中的/data路径已经存在,Docker会使用/host/data的内容覆盖该目录,与mount命令行为一致

    数据卷的备份、转储和迁移

    使用如下命令将数据卷中的数据打包,并将打包后的文件拷贝到主机当前目录中
    docker run --rm --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf

    上述命令创建了一个容器,该容器挂载了dbdata数据卷,并将主机的当前目录挂载到容器的/backup目录中;然后在容器中使用tar命令将dbdata数据卷中的内容打包存放到/backup目录的backup.tar文件中。
    待容器执行结束后,备份文件就出现在主机的当前目录。之后可以将备份文件恢复到当前容器或者新创建的容器中,完成数据的备份和迁移工作

    Docker卷管理的问题

    • 只支持本地数据卷
    • 缺乏对数据卷生命周期的有效管理

    使用卷插件

    卷插件简介

    开发者可以根据自己的需要开发卷插件,可以更方便、更灵活地将本机或远端的存储卷挂载到本机的容器中,提供比Docker自身的卷管理更丰富的功能(如快照、备份等)

    已有的卷插件

    • Convoy 一种基于本地存储的单机版插件
    • Flocker 支持多种后台存储驱动

    Docker API

    关于Docker API

    REST简介

    REST Representational State Transfer 一般来说只要一个架构设计满足REST,就可以称之为RESTful架构

    Docker安全

    深入理解Docker的安全

    Docker的安全性

    Docker安全性主要体现如下几个方面

    • Docker容器的安全性:这是指容器是否会危害到host或其他容器
    • 镜像的安全性:用户如何确保下载下来的镜像是可信的、未被篡改的
    • Docker daemon的安全性:如何确保发送给daemon的命令是可信用户发起的。

    Docker容器的安全性

    安全策略

    Cgroup

    Docker如何使用Cgroup

    • 限制CPU
    • 限制内存
    • 限制块设备 I/O

    ulimit

    Linux系统中有一个ulimit指令,可以对一些类型的资源起到限制作用,包括core dump文件的大小、进程数据段的大小、可创建文件的大小、常驻内存集的大小、打开文件数量、进程栈的大小、CPU时间、单个用户的最大线程数、进程的最大虚拟内存等

    容器组网

    在接入容器隔离不足的情况下,将受信任的和不受信任的容器组网在不同的网络中,可以减少危险

    容器+全虚拟化

    如果将容器运行在全虚拟化环境中(例如在虚拟机中运行容器),这样就算容器被攻破,也有虚拟机的保护作用

    镜像签名

    当发布者将镜像push到远程仓库时,Docker会对镜像用私钥进行签名,之后其他人pull镜像时,Docker就会用发布者的公钥来校验该镜像是否和发布者所发布的镜像一致,是否被篡改,是否是最新版

    日志审计

    目前支持的类型nonejson-filesysloggelffluentd,默认为json-file

    监控

    在使用容器时,应该注意监控容器的信息,若发现异常,就能采取措施及时补救

    文件系统级防护

    Docker可以设置容器的根文件系统为只读模式,只读模式的好处是即使容器与host使用的是同一文件系统,也不用担心会影响甚至破坏host的根文件系统

    capability

    打破了Linux操作系统中超级用户/普通用户的概念,让普通用户也可以做只有超级用户才能完成的工作

    SELinux

    Security-Enhanced Linux 美国国家安全局对于强制访问控制的实现,在这种访问控制体系下,进程只能访问那些在它的任务中所需要的文件

    AppArmor

    其主要作用是设置某个可执行程序的访问控制权限

    Seccomp

    Seccompsecure computing mode)是一种Linux内核提供的安全特性,可以实现应用程序的沙盒机制,以白名单或黑名单的方式限制进程进行系统调用

    grsecurity

    可以用来控制资源访问权限

    几个与Docker安全相关的项目

    • Notary 保证serverclient之间的交互使用可信任的连接
    • docker-bench-security 检测用户的生产环境是否符合Docker的安全实践

    安全加固

    主机逃逸

    利用虚拟机软件或虚拟机中运行的软件漏洞进行攻击,以达到攻击或控制虚拟机宿主操作系统的目的

    后记

    本书链接 Docker进阶与实战

    若文中有错误欢迎大家评论指出,或者加我微信好友一起交流gm4118679254,如果有需要此书pdf版可以私信我

    for My best wishes
  • 相关阅读:
    23 数字时钟&长图滚动
    22 日期特效&长图滚动
    彻底澄清c/c++指针概念
    已管理员模式运行批处理路径丢失问题的解决方法
    使用mathjax在博客中完美显示数学公式,支持PC,手机浏览器
    GOOGLE高级搜索技巧
    我要搬家
    简单的3proxy配置
    AutoMapper小结
    专业IT培训机构-传智播客
  • 原文地址:https://www.cnblogs.com/ccylovehs/p/15650749.html
Copyright © 2020-2023  润新知