基本概念

Docker 是什么

Docker 起初是 dotCloud 公司创始人 Solomon Hykes 在法国的时候发起的一项公司内部项目,Docker 是基于 dotCloud 公司多年云服务技术的一次革新,在 2013 年 3 月以 Apache 2.0 授权协议进行开源,其项目主要代码在 GitHub 上进行维护,自从 Docker 开源之后,就一直受到了广泛讨论和关注。

Docker 进行开发实现使用的是 Google 公司推出的 Go 语言,对进程进行封装隔离是基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,这属于操作系统层面的虚拟化技术。因为隔离的进程独立于宿主与其它隔离的进程,所以也称其为容器(后文会对“容器”的概念进行详细介绍)。Docker 在容器的基础上,进行了进一步的封装,从网络互联、文件系统到进程隔离等,大大地简化了容器的创建和维护,让 Docker 技术比虚拟机技术更加轻便、快捷。

以下两张图片对比了 Docker 与传统虚拟化方式的不同之处。Docker 容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,没有进行硬件虚拟;而传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程。因此容器要比传统虚拟机更为轻便。

图为 传统虚拟化

图为 Docker

为什么要使用 Docker?

Docker 是一种新兴的虚拟化方式,跟传统的虚拟化方式相比具有众多优势。

  • 系统资源利用更高效

因为容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,所以 Docker 对系统资源的利用率更高。

  • 启动时间更快速

Docker 容器应用由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。极大地节省了开发、测试,部署的时间。

  • 运行环境一致性

开发过程中比较常见的问题就是环境一致性问题。因为开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 “这段代码在我机器上没问题啊!”这类问题。

  • 持续交付与部署

对开发和运维人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合持续集成(Continuous Integration)系统进行集成测试,而运维人员则可以直接在各种环境中快速部署该镜像,甚至结合持续部署(Continuous Delivery/Deployment) 系统进行自动部署。

而且使用 Dockerfile 使镜像构建透明化,不仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好地在生产环境中部署该镜像。

  • 迁移更轻松

由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻松地将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境变化导致应用无法正常运行的情况。

  • 维护和扩展更轻松

Docker 使用的分层存储以及镜像技术,使得应用重复部分的复用更为容易,也使得应用的维护更新和基于基础镜像进一步扩展镜像变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大降低了应用服务的镜像制作成本。

Docker 的镜像和容器

Docker 的口号是“Build, Ship and Run Any App, Anywhere.”,大意是编译好一个应用后,可以在任何地方运行,不会像传统的程序一样,一旦换了运行环境,往往就会出现缺这个库,少那个包的问题。那么 Docker 是怎么做到这点的呢?

简单说就是它在编译应用的时候把这个应用依赖的所有东西都构建到镜像里面(有点像程序的静态编译——只是像而已)。我们把这个编译构建好的东西叫 Docker 镜像(Image),然后当 Docker deamon(Docker 的守护进程/服务进程)运行这个镜像的时候,我们称其为 Docker 容器(Container)。可以简单理解 Docker 镜像和 Docker 容器的关系就像是程序和进程的关系一样(当然实质是不一样的)。

Images 和 Layers

每个 Docker 镜像(Image)都引用了一些只读的(read-only)层(layer),不同的文件系统 layer 也不同。这些 layer 堆叠在一起构成了容器(Container)的根文件系统(root filesystem)。下图是 Ubuntu 15.04 的镜像,共由 4 个镜像层(image layer)组成:

Container 和 Layers

容器和镜像的主要区别就是顶部的那个可写层(即之前说的那个“container layer”)。容器运行时做的所有操作都会写到这个可写层里面,当容器删除的时候,这个可写层也会被删掉,但底层的镜像依旧保持不变。所以,不同的容器都有自己的可写层,但可以共享同一个底层镜像。下图展示了多个容器共享同一个 Ubuntu 15.04 镜像。

Docker 的 storage driver 负责管理只读的镜像层和可写的容器层,当然不同的 driver 实现的方式也不同,但其后都有两项关键技术:可堆叠的镜像层(stackable image layer)和写时拷贝技术(copy-on-write, CoW)。

Docker 数据持久化

刚开始的时候,Docker 一般只适用于无状态的计算场景使用。但随着发展,Docker 通过 data volume 技术也可以做到数据持久化了。Data volume 就是我们将主机的某个目录挂载到容器里面,这个 data volume 不受 storage driver 的控制,所有对这个 data volume 的操作会绕过 storage driver 直接其操作,其性能也只受本地主机的限制。而且我们可以挂载任意多个 data volume 到容器中,不同容器也可以共享同一个 data volume。

下图展示了一个 Docker 主机上面运行着两个容器.每一个容器在主机上面都有着自己的地址空间(/var/lib/docker/…),除此以外,它们还共享着主机上面的同一个/data 目录。

Kubernetes 简介

Kubernetes 是谷歌开源的容器集群管理系统,是 Google 多年大规模容器管理技术 Borg 的开源版本,主要功能包括:

  • 于容器的应用部署、维护和滚动升级
  • 负载均衡和服务发现
  • 跨机器和跨地区的集群调度
  • 自动伸缩
  • 无状态服务和有状态服务
  • 广泛的 Volume 支持
  • 插件机制保证扩展性

Kubernetes 发展非常迅速,已经成为容器编排领域的领导者。

Kubernetes 是什么

Kubernetes 提供了很多的功能,它可以简化应用程序的工作流,加快开发速度。通常,一个成功的应用编排系统需要有较强的自动化能力,这也是为什么 Kubernetes 被设计作为构建组件和工具的生态系统平台,以便更轻松地部署、扩展和管理应用程序。

用户可以使用 Label 以自己的方式组织管理资源,还可以使用 Annotation 来自定义资源的描述信息,比如为管理工具提供状态检查等。

此外,Kubernetes 控制器也是构建在跟开发人员和用户使用的相同的 API 之上。用户可以编写自己的控制器和调度器,也可以通过各种插件机制扩展系统的功能。这种设计使得用户可以方便地在 Kubernetes 之上构建各种应用系统。

Kubernetes 不是什么

Kubernetes 不是一个传统意义上,包罗万象的 PaaS (平台即服务) 系统。它给用户预留了选择的自由。

  • 不限制支持的应用程序类型,它不插手应用程序框架, 也不限制支持的语言 (如 Java, Python, Ruby 等),Kubernetes 旨在支持极其多样化的工作负载,包括无状态、有状态和数据处理工作负载。只要应用可以在容器中运行,那么它就可以很好地在 Kubernetes 上运行。
  • 不提供内置的中间件 (如消息中间件)、数据处理框架 (如 Spark)、数据库 (如 mysql) 或集群存储系统 (如 Ceph) 等。这些应用直接运行在 Kubernetes 之上。
  • 不提供点击即部署的服务市场。
  • 不直接部署代码,也不会构建用户的应用程序,但用户可以在 Kubernetes 之上构建需要的持续集成 (CI) 工作流。
  • 允许用户选择自己的日志、监控和告警系统。
  • 不提供应用程序配置语言或系统 (如 jsonnet)。
  • 不提供机器配置、维护、管理或自愈系统。

另外,已经有很多 PaaS 系统运行在 Kubernetes 之上,如 Openshift, Deis 和 Eldarion 等。 你也可以构建自己的 PaaS 系统,或者只使用 Kubernetes 管理你的容器应用。

当然了,Kubernetes 不仅仅是一个 “编排系统”,它消除了编排的需要。Kubernetes 通过声明式的 API 和一系列独立、可组合的控制器保证了应用总是在期望的状态,而用户并不需要关心中间状态是如何转换的。这使得整个系统更容易使用,而且更强大、更可靠、更具弹性和可扩展性。

基本组件

核心组件

Kubernetes 主要由以下几个核心组件组成:

  • etcd:保存了整个集群的状态;
  • apiserver:提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制;
  • controller manager:负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • scheduler:负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上;
  • kubelet:负责维护容器的生命周期,同时也负责 Volume(CVI)和网络(CNI)的管理;
  • Container runtime:负责镜像管理以及 Pod 和容器的真正运行(CRI);
  • kube-proxy:负责为 Service 提供 cluster 内部的服务发现和负载均衡

除了核心组件,还有一些推荐的 Add-ons:

  • kube-dns:负责为整个集群提供 DNS 服务
  • Ingress Controller:为服务提供外网入口
  • Heapster:提供资源监控
  • Dashboard:提供 GUI
  • Federation:提供跨可用区的集群
  • Fluentd-elasticsearch:提供集群日志采集、存储与查询

组件详细介绍

Etcd

Etcd 是 CoreOS 基于 Raft 开发的分布式 key-value 存储,可用于服务发现、共享配置以及一致性保障(如数据库选主、分布式锁等)。

Etcd 主要功能:

  • 基本的 key-value 存储
  • 监听机制
  • key 的过期及续约机制,用于监控和服务发现
  • 原子 CAS 和 CAD,用于分布式锁和 leader 选举

kube-apiserver

kube-apiserver 是 Kubernetes 最重要的核心组件之一,主要提供以下的功能:

  • 提供集群管理的 REST API 接口,包括认证授权、数据校验以及集群状态变更等
  • 提供其他模块之间的数据交互和通信的枢纽(其他模块通过 API Server 查询或修改数据,只有 API Server 才直接操作 etcd)

kube-controller-manager

Controller Manager 由 kube-controller-manager 和 cloud-controller-manager 组成,是 Kubernetes 的大脑,它通过 apiserver 监控整个集群的状态,并确保集群处于预期的工作状态。

kube-controller-manager 由一系列的控制器组成

  • Replication Controller
  • Node Controller
  • CronJob Controller
  • Daemon Controller
  • Deployment Controller
  • Endpoint Controller
  • Garbage Collector
  • Namespace Controller
  • Job Controller
  • Pod AutoScaler
  • RelicaSet
  • Service Controller
  • ServiceAccount Controller
  • StatefulSet Controller
  • Volume Controller
  • Resource quota Controller

cloud-controller-manager

在 Kubernetes 启用 Cloud Provider 的时候才需要,用来配合云服务提供商的控制,也包括一系列的控制器,如:

  • Node Controller
  • Route Controller
  • Service Controller

kube-scheduler

kube-scheduler 负责分配调度 Pod 到集群内的节点上,它监听 kube-apiserver,查询还未分配 Node 的 Pod,然后根据调度策略为这些 Pod 分配节点(更新 Pod 的 NodeName 字段)。

调度器需要充分考虑诸多的因素:

  • 公平调度
  • 资源高效利用
  • QoS
  • affinity 和 anti-affinity
  • 数据本地化(data locality)
  • 内部负载干扰(inter-workload interference)
  • deadlines

Kubelet

每个节点上都运行一个 kubelet 服务进程,默认监听 10250 端口,接收并执行 master 发来的指令,管理 Pod 及 Pod 中的容器。每个 kubelet 进程会在 API Server 上注册节点自身信息,定期向 master 节点汇报节点的资源使用情况,并通过 cAdvisor 监控节点和容器的资源。

Container runtime

容器运行时(Container Runtime)是 Kubernetes 最重要的组件之一,负责真正管理镜像和容器的生命周期。Kubelet 通过 Container Runtime Interface (CRI) 与容器运行时交互,以管理镜像和容器。

kube-proxy

每台机器上都运行一个 kube-proxy 服务,它监听 API server 中 service 和 endpoint 的变化情况,并通过 iptables 等来为服务配置负载均衡(仅支持 TCP 和 UDP)。

kube-proxy 可以直接运行在物理机上,也可以以 static pod 或者 daemonset 的方式运行。

kube-proxy 当前支持一下几种实现:

  • userspace:最早的负载均衡方案,它在用户空间监听一个端口,所有服务通过 iptables 转发到这个端口,然后在其内部负载均衡到实际的 Pod。该方式最主要的问题是效率低,有明显的性能瓶颈。
  • iptables:目前推荐的方案,完全以 iptables 规则的方式来实现 service 负载均衡。该方式最主要的问题是在服务多的时候产生太多的 iptables 规则,非增量式更新会引入一定的时延,大规模情况下有明显的性能问题
  • ipvs:为解决 iptables 模式的性能问题,v1.8 新增了 ipvs 模式,采用增量式更新,并可以保证 service 更新期间连接保持不断开
  • winuserspace:同 userspace,但仅工作在 windows 上。

Kubernetes 架构

K8s 设置由几个部分组成,其中一些是可选的,一些是整个系统运行所必需的。下面是 k8s 的全局架构图:

Kubernetes 有两个不同的部分构成,一个是 Master,一个是 Node。Master 负责调度资源和为客户端提供 API,客户端可以是 UI 界面或者 CLI 工具,在 Kubernetes 中 CLI 工具通常为 kubectl。 Kubernetes Master 接受使用 YAML 定义的配置文件,根据配置文件中相关信息将容器分配到其中一个 Node 上。另外,镜像库在 Kubernetes 中也起到一个很重要的角色,Kubernetes 需要从镜像库中拉取镜像基于这个镜像的容器才能成功启动。常用的镜像库有 dockerhub、阿里云镜像库等。下面图片为 Master 的架构图:

Master 有三个组件:API Server、Scheduler、Controller。API Server 提供了友好易用的 API 供外部调用,同时有很多强大的工具使得 API 调用更加简单,如 kubectl 封装了大量 API 调用,使得部署、配置更加简单。Kubernetes-dashboard 可以让用户在界面上操作 Kubernetes,而无需手动输入各个 API 的调用地址参数等信息。

当 API Server 收到部署请求后,Scheduler 会根据所需的资源,判断各节点的资源占用情况分配合适的 Node 给新的容器。判断依据包括内存、CPU、磁盘等。

Controller 负责整个集群的整体协调和健康,保证每个组件以正确的方式运行。

在图的最下边是 ETCD 数据库。如前文所述 ETCD 是分布式存储数据库,其作为 Kubernetes 的中央数据库,存储了集群的状态,组件可以通过查询 ETCD 了解集群的状态。

Kubernetes Master 分配容器到 Node 执行,Node 将会承受压力,通常情况下新容器不会运行在 Master 上。或者说 Master 是不可调度的,但是你也可以选择把 Master 同时也作为 Node,但是这并不是地道的用法。下面的为 Node 的架构图:

Kube-proxy 在 Node 中管理网络,其左右至关重要。Kube-proxy 通过管理 iptables 等方式使得 pod 到 pod 之间,和 pod 到 node 之间网络能够互通。实质上在跨主机的 pod 之间网络也能够互通。

Kubelet 负责向 api server 报告信息,并把健康状态、指标和节点状态信息存入 ETCD 中。

Docker 上文已详细介绍这里就不多做阐述。

Supervisord 保证 Docker 和 kubelet 一直在运行中,supervisord 并不是必须组件,可以使用其他类似组件替换。

Pod 是可以在 Kubernetes 中创建和管理的最小可部署计算单元。一个 POD 中可以包含多个容器,但 Kubernetes 仅管理 pod。如果多个容器运行在一个 POD 中,就相当于这些容器运行在同一台主机中,需要注意端口占用问题。

参考资料

https://yeasy.gitbooks.io/docker_practice/content/introduction/what.html

https://yeasy.gitbooks.io/docker_practice/content/introduction/why.html

https://docs.docker.com/storage/storagedriver/

https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/

http://k8s.docker8.com/

https://www.youtube.com/watch?v=zeS6OyDoy78

 【相关文章】
从0到1使用Kubernetes系列(一):Kubernetes入门
从0到1使用Kubernetes系列(二):安装工具介绍
从0到1使用Kubernetes系列(三):使用Ansible安装Kubernetes集群
从0到1使用Kubernetes系列(四):搭建第一个应用程序
从0到1使用Kubernetes系列(五):Kubernetes Scheduling
从0到1使用Kubernetes系列(六):数据持久化实战
从0到1使用 Kubernetes 系列(七):网络
从0到1使用Kubernetes系列(八):Kubernetes安全


本文由猪齿鱼技术团队原创,转载请注明出处:猪齿鱼官网

关于猪齿鱼

猪齿鱼Choerodon全场景效能平台,提供体系化方法论和协作、测试、DevOps及容器工具,帮助企业拉通需求、设计、开发、部署、测试和运营流程,一站式提高管理效率和质量。从团队协同到DevOps工具链、从平台工具到体系化方法论,猪齿鱼全面满足协同管理与工程效率需求,贯穿端到端全流程,助力团队效能更快更强更稳定。戳此处试用猪齿鱼

标签智能推荐:

2020年中国DevOps应用发展研究——艾瑞咨询报告总结

s市场现状:早在云计算诞生之前DevOps已然存在,长期以来DevOps实践使用的软件工具以免费的开源软件为主。尽管如此,一体化的DevOps平台正在成为全球范围内的DevOps发展趋势,国内企业通常采用一体化平台+开源软件的方式构建自己的DevOps体系。2020年国内DevOps服务的市场规模达到27亿元,未来5年的CAGR将超过25%,市场发展前景良好。DevOps应用展望:DevOps面对

原生推动全开发与实践

拥抱云计算和云原生,进行数字化创新和升级,云原生内涵得到了极大丰富,使得我们今天可以重新定义云原生。云原生技术的出现,有利于帮助开发者构建弹性扩展、容错性好、易于管理,便于观测的松耦合系统,代表技术Kubernetes、容器、DevOps、微服务、服务网格、Serverless,可以看到,这样的技术是一组应用层技术的集合,而云计算的传统优势是资源的池化,这种集约化管理,会带来弹性分布式和基于API

活动推荐 | 中国 DevOps 社区深圳第十届 MeetUp 来啦!

强CODING高级解决方案架构师演讲主题《DevOps端到端价值流交付的设计、思考与实践》具有一线互联网、物联网独角兽、全国股份制银行、新型智慧交通等跨行业从业经历,历任Java开发高级工程师、DevOps技术专家、高级研发经理等职,对微服务、敏捷、DevOps、容器技术有深刻的理解和丰富的实践。现任CODING高级解决方案架构师,负责CODINGDevOps解决方案架构设计和技术产品布道;负责C

《第四期(2021-2022)传统行业原生技术落地调研报告——金融篇》重磅发布!

来临,以容器、微服务为代表的云原生技术带来了一种全新的方式来开发、交付、迭代企业应用,重塑着传统行业的业务体系,加速着企业自身、以及产业生态的转型升级。在此背景下,云原生技术实践联盟(CNBPA)联合云原生技术社区,以及灵雀云、F5、SmartX、青藤云安全、码云等云原生技术厂商,共同发起了《第四期(2021-2022)传统行业云原生技术落地调研》,今年首次以聚焦行业的形式,深入探讨云原生技术对金

演讲实录 | 基于原生的敏态微服务全生命周期支撑平台

业共同参与,以推动技术变革,适应时代发展。在12月17日下午的“云原生领导力论坛”上,博云售前解决方案架构师庞玉海带来《基于云原生的敏态微服务支撑平台》为题的主题演讲。演讲围绕什么是云原生,云原生的技术特征及优势、博云落地的实践经验三个方面展开。 什么是云原生云原生是一系列的云计算的体系和企业管理的方法的集合,它的核心概念在于它是一套技术体系和管理方法,而不能说是靠一个技术平台就能解决,

原生热点技术国内使用现状 | 趋势分享

云原生产业发展的强劲驱动力,“新基建”带来的万亿级资本投入,也将在未来几年推动云原生产业的发展迈向新阶段。据云原生产业联盟相关调研数据显示,云原生产业作为现阶段云计算PaaS市场的重要支点,2019年我国云原生产业市场规模已达350.2亿元,未来还将延续高速增长态势。10月21日,云原生产业联盟于2020云原生产业大会发布了国内首个《中国云原生用户调研报告(2020年)》(以下简称“报告”),详细

.NET平台系列21:原生时代 .NET5 雄霸天下

nbsp;  随着互联网持续高歌猛进,相关技术名词也是层出不穷。微服务、容器化、DevOps、ServerLess、FaaS,这两年最火的当属云原生CloudNative!当下大部分企业还在追逐微服务架构落地,而下一代的架构云原生已如火如荼。CloudNative云原生何谓云原生?技术的变革,一定是思想先行,云原生是一种构建和运行应用程序的方法,是一套技术体系和方法论,是在云计

原生技术赋能ISV实现应用现代化

盟,促进会员间的技术交流和业务合作,推动联盟成员资源共享,推进以云原生技术为导向的新型数字生态的健康发展。未来,联盟作为中立机构,还将以官方推广形式助力ISV企业打造技术影响力和行业口碑,构建技术品牌护城河;还将定期组织联盟成员闭门研讨,交流云原生领域技术趋势和各ISV的云原生实践,推动联盟资源共享;同时,来自英特尔中国和灵雀云的云原生技术顾问还将无偿为联盟成员提供应用向云原生迁移和应用现代化改造

东吴证券张之浩:从理论到落地的 DevOps 体系建设

署以及最后上线,对于研发队伍和信息技术比较关键。我们怎么拥抱云原生,接受云原生,我们希望把内外网隔离,我的发布往往是层层审核,最后是手工部署上线,因为我们的信息安全要求,包括系统可用性要求是非常高的,怎么通过云原生技术的手段,提升整个的代码质量、提升整个技术系统的稳定性,这个值得探索,券商端90以上的券商,系统的上线和部署是通过手工方式去做,我们怎么通过云原生能够高效、高可用、可收缩,怎么能够实现

成为容器代表性厂商,入选Gartner《2020年中国ICT技术成熟度曲线报告》

上,当前容器技术收益合理,市场潜力覆盖了5%-20%的目标受众,技术成熟度凸显。Gartner指出,以BoCloud博云为代表的国内容器服务提供商是强有力的本土竞争者。博云深耕容器领域,掌握底层核心能力近年来,容器技术凭借轻量化和标准化的显著特性,逐渐成为云计算领域基础设施云化的变革技术。作为云原生(cloudnative)生态的基石,容器技术已然成为云原生时代的标准基础设施。作为国内最早瞄准容器