Docker 使用 client-server 架构模式。Docker 客户端通过发出指令与服务端进行交互,完成构建、运行、发布等诸多对容器的操作。Docker 客户端可以与服务端守护进程运行与同一个操作系统,使用本地通信的方式连接服务端。此外,Docker 客户端也可以使用远程连接的方式与服务端进行通信。客户端通过 UNIX 套接字或网络地址与守护进程的 REST API 进行通信。
1. docker 守护进程 dockerd
监听 docker API 并处理来自客户端的请求,以管理 docker 中的资源或对象,例如 image、containers、network、volume 等。2. docker client docker
是与 docker 交互的主要方式。当您使用例如 docker run
命令发送给 dockerd
守护进程后,dockerd 守护进程将执行用户发送的命令。3. docker registries 中存储 docker 镜像, Docker Hub 是一个公共的镜像仓库,也是 docker 默认拉取上传的镜像仓库。4. image 是有创建容器说明的只读模板,通常一个镜像基于另一个镜像并添加个性化定制而成,例如基于 ubuntu
制作一个基础镜像,并可以自定义安装 Apache
、MySQL
以及自己开发的应用程序等。使用镜像的两种途径为:自己制作、使用公共仓库镜像。要构建自己的镜像,可以使用简单的语法创建一个 Dockerfile,以定义创建镜像并运行它所需的步骤。Dockerfile 中的每一条指定都将在镜像之上创建一层。当更改 Dockerfile 并重新构建镜像后,将仅仅改变变化的部分,这也是较其他虚拟化技术相比,Docker 更轻量化和快速的重要原因。5. Container 是一个镜像运行的实例,用户可以使用 Docker API 或 CLI 创建、启动、停止、移动、删除一个容器。默认情况下,一个容器相对于其他容器和主机之间是高度隔离的,你也可以控制网络、存储等对外的连接程度。
Docker 使用 Go 语言编写并且借助 Linux 内核的多个高级功能实现了容器的功能。1. namespace:Docker 使用 namespace 名称空间的技术实现了资源隔离,每当创建容器时,Docker 为该容器提供一组名称空间。每类资源都运行于独立的一个名称空间内,并且资源访问权限局限于对应的名称空间内。Docker 引擎使用到的名称空间有 pid、net、ipc、mnt、uts
。2. cgroups:docker 引擎依靠 control groups
技术去限定应用程序使用的资源,并对容器进行限制和约束,例如可以限制容器可使用的内存资源。3. UnionFS :Union file systems
或 UnionFS
是通过创建不同的层进行操作的文件系统并提供构建层,具有轻便,快速的特点。4. container format: Docker 引擎将 namespace、cgroups、UnionFS等集成起来并封装成特定的容器格式,默认容器格式为 libcontainer
。
docker 是供开发人员或系统管理员使用容器 创建、运行和共享程序的一个平台。使用容器去部署应用的方式被称为容器化
。容器化使得部署应用变的异常便捷和灵活,具有轻量(共享宿主机内核,使得相对于传统虚拟化而言利用在资源的效率更高)、灵活、便捷、低耦合、可扩展、安全等特性。
镜像和容器
容器是一个镜像启动的实例,在宿主机机层面表现为一个正在运行的进程。容器的封装功能起到了和其他容器和宿主机之间的隔离功能。实现隔离最重要的核心是每个容器都具有单独且独立的文件系统,该文件系统由 docker image 提供。一个镜像包括了应用程序文件、运行时环境、依赖和其他所需要的文件。
容器和虚拟化
容器之间共享宿主机的内核,在宿主机表现为容器进程。虚拟机则在宿主机之上运行一个完整的操作系统通过虚拟化管理程序访问硬件资源,因此虚拟机会额外带来很大的开销,造成资源浪费。
kubernetes
也简称为 k8s
,在希腊语义中的意思是“舵手”的意思,有趣的是这帮技术人员之所以叫 k8s 是因为 k 和 s 之间有 8 个字母。Kubernetes 的原始代号曾经是 Seven,星际迷航中的 Borg (博格人)。Kubernetes标识中舵轮有七个轮辐就是对该项目代号的致意。kubernetes 是一个开源系统,用于自动化部署、扩展和管理容器的软件。k8s 将应用程序所在的容器分组为逻辑单元,更便于管理和监控。k8s 最初由谷歌的工程师开发,google 有超过 15 年的使用实践经验,每周会用超过 10 亿个容器,这些容器全部都由 kubernetes 的前身 Borg
系统支持。2014 年 kubernetes 首次对外宣布开源。2015 年 7 月 21 日 kubernetes v1.0 版本正式发布。
除了Kubernetes,还有其他的容器编排工具,例如 docker compose
,但这种工具更适用于针对单机编排,不适合多主机或集群的编排。docker 还提供了另外一个编排工具 docker swarm
,它可以将多个docker主机整合成一个资源池,然后进行容器的编排。此外还有另外一个工具,docker machine
,它将主机初始化为 docker hos t并将它加入 docker swarm 管理的资源池中。这三个工具称为docker “三剑客”。
此外 mesos
也可以将各种资源进行抽象,将资源抽象成一个大的资源池,它向上提供一个程序使用的资源调度工具,并不能运行容器,但有另外一个框架,marathon
框架可以运行容器。
开源的 kubernetes 是完全原生的功能,没有任何商业支持,当出现问题时可能不发解决,或者某些功能不够符合企业需求。因此衍生出一批 kubernetes 的商业发行版,如:红帽的OpenShift、CoreOS的Tectonic等。
微服务是一种软件架构风格,使用单一的功能模块组成一个复杂的大型应用,各模块功能之间与编程语言无关,各模块之间使用API通信。与去相对应的是单体式应用程序,其包含了应用程序的所有功能模块。
云原生定义
云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。
这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。
云原生计算基金会(CNCF)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。我们通过将最前沿的模式民主化,让这些创新为大众所用。
云原生是一种基础设施,运行在其上的应用称为云原生应用,符合云原生设计哲学的应用的架构叫云原生应用架构。
CNCF定义
CNCF(Cloud Native Computing Foundation)云原生计算基金会是一个开源软件基金会,致力于支持和推广云原生计算开源技术,例如 Kubernetes、Prometheus 等,云原生计算使开源软件将应用部署为微服务,将每个部分打包到自己的容器中,并动态编排这些容器以优化资源利用。官方 github 仓库:https://github.com/cncf/。CNCF 的使命是推广:容器化;通过中心编排系统的动态资源管理;面向微服务。
DevOps
(Development Operations)是一种注重开发人员和运维人员沟通的一种文化和运动。DevOps旨在建立使得软件的构建、测试、发布能够快捷和可靠的流程或方法。
Kubernetes Master
是一个运行了三个进程的集合的单个节点,我们称之为主节点。这三个进程包括:kube-apiserver
、kubcontroller-manager
、kub-scheduler
。其他非主节点上运行的进程有:kubelet
、kube-proxy
。
Kubnernetes Object:(代表系统状态的抽象,例如应用程序、负载、网络、磁盘资源、正在执行的操作等,这些抽象由 Kubnernetes API 表示。)
- Pod
- Service
- Volume
- Namespace
Kubernetes Controller:(更高级的抽象,控制器。)
- ReplicaSet
- Deployment
- StatefulSet
- DaemonSet
- Job
Kubernetes Control Plane:(控制平面)
管理和控制 Kubernetes 集群中对象的状态使得和定义的状态一致。
Kubernetes
是一个可移植且易于扩展的管理容器的负载和服务的开源平台,更便于实现声明性配置和自动化的实现。Kubernetes 具有 Paas 平台的简单性以及 IaaS 平台的灵活性。
Kubernetes 使用 Labels
可以使用户自由的组织资源,Annotations
使用户能够自定义标记资源。此外,Kubernetes 有可供开发人员和用户使用的 Control Plane,而 Control Plane 是基于API构建的,用户甚至可以自己编写控制器,例如调度程序。这种设计方式使得许多系统能够基于 Kubernetes 构建。
Kubernetes 不是一个从传统的包罗万象的 PaaS 平台,Kubernetes 基于容器实现而不硬件级别,因此它提供了 PaaS 平台的一些常用功能,例如部署、扩展、负载均衡、日志及监控。然后这些功能都是插件式的,可选的。
Kubernetes 为什么使用容器?
传统的部署应用的方式是使用操作系统的软件包管理器进行安装部署, 这种方式使得应用程序的执行文件、配置文件、库等和操作系统系统环境文件混在一起,增加了管理难度。尽管能够构建固定的虚拟机镜像以实现快速部署和回滚操作,但虚拟机过于重量级且移植难度大。使用容器的方式进行部署是基于操作系统级别的虚拟化而不是硬件虚拟化来实现的,这些容器彼此隔离且于主机隔离,更节省计算资源,相比于虚拟机更容易构建。因为容器和底层基础架构和操作系统的文件系统等隔离,因此可以跨操作系统、主机甚至是跨云的进行移植和快速部署。
因为容器更轻量级,因此可以在每个容器中打包并部署一个应用程序。使用容器之后,应用程序不需要于应用程序依赖的其余服务结合,解耦了服务之间以及应用程序和操作系统的关系。此外,使用容器和以统一开发环境和生产环境的一致性,容器比虚拟机更易于监控和管理。
容器的优势
- 更快的创建和部署应用程序。
- 持续开发集成和部署。
- 更易于监控应用程序运行状态。
- 开发、测试、成产环境一致性。
- 跨平台移植。
- 松耦合、分布式、微服务、弹性计算。
- 资源隔离。
- 更高的资源利用效率。
Master组件提供了集群控制平面。Master组件负责集群的全局事务,例如调度、监测及响应集群时间(当定义的控制器副本少于定义的数量时启动新的副本)。Master的组件能够运行在任何虚拟机或主机之上,但为了简单起见,通常会在同一台主机或虚拟机上运行所有组件。
kube-apiserver
该组件暴露Kubernetes的控制API,它是Kubernetes的控制平面前端。
etcd
键值存储组件,用作Kubernetes集群数据的存储。
kube-scheduler
用于监视并把将新创建的 pod 选择运行到主机上。
kube-controller-manager
逻辑上每个控制器都是独立的,为了降低复杂度,每个控制器都被编译成单个二进制文件。控制器相当于状态机,用于控制Pod的具体状态和行为。控制器包括:
- Node Controller,节点控制器。负责监控节点的故障。
- Replicaton Controller,副本控制器。负责维护所定义的pods副本数。
- Endpoints Controller,端点控制器。
- Service Account & Token Controllers,服务帐户和令牌控制器。为新的命名空间创建默认帐户和 API 访问令牌.
node 组件运行在每个node组件之上,维持和监控运行的pod并提供Kubernetes运行时环境。
kubelet
集群代理,运行在每个节点的代理程序,它确保容器在pod中的正常运行。接收 Master 发出的调度管理请求。
kub-proxy
负责维护主机上的网络规则并执行转发。
Container Runtime
负责运行容器的软件。Kubernetes支持Docker、containerd、cri-o、rktlet以及符合Kubernetes CRI(Container Runtime Interface)接口的任何运行容器软件的实现。
DNS
为Kubernetes集群中的服务提供DNS服务。Kubernetes启动的容器会在DNS搜索中自动包含这个DNS服务器。此 DNS 以 Pod 的形式在集群中运行。
web UI(Dashboard)
一个基于web的通用UI,用户可以通过UI界面管理和管理和监控集群中的应用程序及集群本身。
Container Resource Monitoring
容器资源监控并提供用于查看该数据的UI。
Cluster-level Logging
负责将容器日志保存到具有搜索和查看功能的中心日志存储中。
Pod 是 kubernetes 调度的最小单元,一个 Pod 中可运行多个容器。Pod 之上可以附加各类属性标签 Label,还可以使用 Label Selector 进行过滤和选择 Pod。 利用 Pod 可以进行滚动更新和回滚操作。
计划 > 开发 > 构建 > 测试 > 修复bug > 测试 (持续集成)
自动将充分测试的应用交付给运维人员可以自动取到的仓库 (持续交付)
运维人员将项目自动部署,容器技术可以运行再不同的平台之上 (持续部署)
容器和编排技术使得 DevOps 使得以上这些技术可以实现。
ReplicationController
是ReplicaSet
控制器的前生,官方建议使用Deployment控制器,不建议单独使用ReplicaSet控制器,ReplicaSet支持动态的扩容和缩容、更新升级。Deployment
控制器工作与ReplicaSet
之上,创建Deployment时会自动创建replicaset控制器。Deployment控制器通过控制ReplicaSet控制器进而控制pod。Deployment支持滚动更新、回滚操作,此外,支持声明式配置,动态更新状态等。deployment只能管控无状态的应用的pod。DaemonSet
用于需要在集群中的每一个节点或部分节点上上运行一个单独的进程,在用于在部分节点上运行单独的进程时,需要用到节点标签选择器。job
控制器用于pod只执行一次性的任务的场景。Cronjob
控制器用来周期性的执行某一个任务。StatefulSet
能够单独管理有状态的pod应用,每一个应用都有独有的标识。CDR,Custom Defined Resources
,1.8版本之后引入。strategy
配置字段可配置更新策略。其支持两种更新策略 deployment.spec.strategy.type 进行制定更新策略类型,分别为 Recreate
(重建更新,即更新一个删除一个)和RpllingUpdate
rollingUpdate
时,可使用 rollingUpdate 配置其滚动更新方式,其配置字段有 maxSurge
和maxUnavailable
。maxSurge
表示可以超出制定pod副本数的数量,比如可以超出两个或四个,还可以使用百分比进行指定。maxUnavailable
则表示在保证预期状态pod数量的正常的基础上最多允许有多少个不可用。金丝雀发布
kubectl rollout pause deployment app-deployment
,修改发布后,更新一个pod成功之后暂停更新,待未发现异常则继续进行更新。kubectl resume pause deployment app-deployment