Docker基础 - 01介绍
一、虚拟化
1.1 主机级虚拟化
Type-I: 在操作系统的基础上,虚拟网络设备
Type-II: 在物理硬件的基础上
1.2 Linux Namespaces
namespace | 系统调用参数 | 隔离内容 | 内核版本 |
UTS | CLONE_NEWUTS | 主机名和域名 | 2.6.19 |
IPC | CLONE_NEWIPC | 信号量、消息队列和共享内存 | 2.6.19 |
PID | CLONE_NEWPID | 进程编号 | 2.6.24 |
Network | CLONE_NEWNET | 网络设备、网络栈、端口等 | 2.6.29 |
Mount | CLONE_NEWNS | 挂载点(文件系统) | 2.4.19 |
User | CLONE_NEWUSER | 用户和用户组 | 3.8 |
1.3 Control Group(cgroups)
- blkio: 块设备IO
- cpu: CPU
- cpuacct: CPU资源使用报告
- cpuset: 多处理器平台上的CPU集合
- devices: 设备访问
- freezer: 挂起或恢复任务
- memory: 内存用量及报告
- perf_event: 对cgroup中的任务进行统一性能测试
- net_cls: cgroup中的任务创建的数据报文的类别标识符
、
1.4 容器级虚拟化
抽取掉GuestOS层, 使用名称空间 和 资源隔离
(1) LinuX Container LXC - create, template
(2) jail, vserver(chroot)
(3) docker容器: lxc -> libcontainer -> runC
(4) runC
- OCF: Open Container Format
- runC is a CLI tool for spawning and running containers according to the OCI specification。
- Containers are started as a child process of runC and can be embedded into various other systems without having to run a daemon。
- runC is built on libcontainer,the same container technology powering millions of Docker Engine installations。
(5) OCI: Open Container Initiative
- 由Linux基金会主导于2015年6月创立,旨在围绕容器格式和运行时制定一个开放的工业化标准
- contains: the Runtime Specification(runtime-spec) / the Image Specification(image-spec)
- The Runtime Specification outlines how to run a "filesystem bundle" that is unpacked on disk。
- At a high-level an OCI implementation would download an OCI Image then unpack that image into an OCI Runtime filesystem bundle。
二、Docker
2.1 介绍
Docker 是 PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在Github上,基于go语言并遵从Apache2.0协议开源。
Docker自2013年以来非常火热,无论是从 github 上的代码活跃度,还是Redhat在RHEL6.5中集成对Docker的支持, 就连Google的Compute Engine也支持docker在其之上运行。
CoreOS / Moby / CNCF
2.2 引入背景
环境管理复杂
- 从各种OS到各种中间件到各种app, 一款产品能够成功作为开发者需要关心的东西太多,且难于管理,这个问题几乎在所有现代IT相关行业都需要面对。
云计算时代的到来
- AWS的成功, 引导开发者将应用转移到 cloud上, 解决了硬件管理的问题,然而中间件相关的问题依然存在 (所以openstack HEAT和 AWS cloudformation 都着力解决这个问题)。
虚拟化手段的变化
- cloud 时代采用标配硬件来降低成本,采用虚拟化手段来满足用户按需使用的需求以及保证可用性和隔离性。
- 无论是KVM还是Xen在 docker 看来,都在浪费资源,因为用户需要的是高效运行环境而非OS, GuestOS既浪费资源又难于管理, 更加轻量级的LXC更加灵活和快速
LXC的移动性
- LXC在 linux 2.6 的 kernel 里就已经存在了,但是其设计之初并非为云计算考虑的,缺少标准化的描述手段和容器的可迁移性,决定其构建出的环境难于迁移和标准化管理(相对于KVM之类image和snapshot的概念)。docker 就在这个问题上做出实质性的革新。这是docker最独特的地方。
2.3 VM技术和容器技术对比
Docker 容器相对于 VM 有以下几个优点:
- 启动速度快,容器通常在一秒内可以启动,而 VM 通常要更久。
- 资源利用率低,一台普通 PC 可以跑上千个容器,你跑上千个 VM 试试。
- 性能开销小, VM 通常需要额外的 CPU 和内存来完成 OS 的功能,这一部分占据了额外的资源。
- 此外容器也和VM一样具有着一定的隔离性,各个容器之间的数据和内存空间相互隔离,可以保证一定的安全性。
为啥相似的功能在性能上会有如此巨大的差距呢,其实这和他们的设计的理念是相关的。
VM 的 Hypervisor 需要实现对硬件的虚拟化,并且还要搭载自己的操作系统,自然在启动速度和资源利用率以及性能上有比较大的开销。
Docker几乎就没有什么虚拟化的东西,并且直接复用了 Host 主机的 OS,在 Docker Engine 层面实现了调度和隔离,重量一下子就降低了好几个档次。
Docker的容器利用了LXC,管理利用了 namespaces 来做权限的控制和隔离, cgroups 来进行资源的配置,并且还通过 aufs 来进一步提高文件系统的资源利用率。
其中的 aufs 是个很有意思的东西,是 UnionFS 的一种。思想和 git 有些类似,可以把对文件系统的改动当成一次 commit 一层层的叠加。
这样的话多个容器之间就可以共享他们的文件系统层次,每个容器下面都是共享的文件系统层次,上面再是各自对文件系统改动的层次,这样的话极大的节省了对存储的需求,并且也能加速容器的启动。
2.4 应用场景
面对上述几个问题,docker设想是交付运行环境如同海运,OS如同一个货轮,每一个在OS基础上的软件都如同一个集装箱,用户可以通过标准化手段*组装运行环境,同时集装箱的内容可以由用户自定义,也可以由专业人员制造。这样,交付一个软件,就是一系列标准化组件的集合的交付,如同乐高积木,用户只需要选择合适的积木组合,并且在最顶端署上自己的名字(最后个标准化组件是用户的app)。这也就是基于docker的PaaS产品的原型。
在docker的网站上提到了docker的典型场景:
- Automating the packaging and deployment of applications
- Creation of lightweight, private PAAS environments
- Automated testing and continuous integration/deployment
- Deploying and scaling web apps, databases and backend services
对于构建隔离的标准化的运行环境、轻量级的PaaS(如dokku)、 构建自动化测试和持续集成环境,以及一切可以横向扩展的应用(尤其是需要快速启停来应对峰谷的web应用)。
<1> 构建标准化的运行环境,现有的方案大多是在一个baseOS上运行一套puppet/chef,或者一个image文件,
其缺点是前者需要base OS许多前提条件,后者几乎不可以修改(因为copy on write 的文件格式在运行时rootfs是read only的)。并且后者文件体积大,环境管理和版本控制本身也是一个问题。
<2> PaaS环境是不言而喻的,其设计之初和dotcloud的案例都是将其作为PaaS产品的环境基础。
因为其标准化构建方法(buildfile)和良好的REST API,自动测试和持续集成/部署能够很好的集成进来。
因为LXC轻量级的特点,其启动快,而且docker能够只加载每个container变化的部分,这样资源占用小,能够在单机环境下与KVM之类的虚拟化方案相比能够更加快速和占用更少资源。
如果利用容器的话,那么开发直接在容器里开发,提测的时候把整个容器给测试,测好了把改动改在容器里再上线就好了。通过容器,整个开发、测试和生产环境可以保持高度的一致。
三、Docker 架构
Docker 平台基本上由三部分组成:
- 客户端: 用户使用 Docker 提供的工具(CLI 以及 API 等)来构建,上传镜像并发布命令来创建和启动容器
- Docker 主机: 从 Docker registry 上下载镜像并启动容器
- Docker registry: Docker 镜像仓库,用于保存镜像,并提供镜像上传和下载。
官网介绍:
The Docker daemon- The Docker daemon (dockerd) listens for Docker API requests and manages Docker objects such as images, containers, networks, and volumes.
- A daemon can also communicate with other daemons to manage Docker services.
- The Docker client (docker) is the primary way that many Docker users interact with Docker.
- When you use commands such as docker run, the client sends these commands to dockerd, which carries them out. The docker command uses the Docker API.
- The Docker client can communicate with more than one daemon.
- A Docker registry stores Docker images.
- Docker Hub is a public registry that anyone can use, and Docker is configured to look for images on Docker Hub by default.
- You can even run your own private registry.
- When you use the docker pull or docker run commands, the required images are pulled from your configured registry.
- When you use the docker push command, your image is pushed to your configured registry.