Kubernetes 有很多技术概念和API对象,每一个都可以扩展讲很多,按照前文的学习思路,还是先了解大概。
Pod
官方对于Pod的解释是:
Pod是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。
Pod 的设计理念是支持多个容器在一个 Pod 中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。
举个简单的例子:比如我们设计了一个商品相关的微服务,包括了商品管理和商品同步(从其他数据源抽取商品)两部分功能,在设计上来说,我们很可能把这两部分拆成2个独立小应用并且由2个小组分别来完成(只是假设)。这种情况下,大可以不同的团队各自开发构建自己的容器镜像,在部署的时候组合成一个微服务对外提供服务,构建一个Pod。
Pod间关系如下图:
同一个 Pod 之间的 Container 可以通过 localhost 互相访问,并且可以挂载 Pod 内所有的数据卷;但是不同的 Pod 之间的 Container 不能用 localhost 访问,也不能挂载其他 Pod 的数据卷。
Volume
Kubernetes 集群中的存储卷跟 Docker 的存储卷有些类似,只不过 Docker 的存储卷作用范围为一个容器,而 Kubernetes 的存储卷的生命周期和作用范围是一个 Pod。每个 Pod 中声明的存储卷由 Pod 中的所有容器共享。Kubernetes 支持非常多的存储卷类型,特别的,支持多种公有云平台的存储,包括 AWS,Google 和 Azure 云;支持多种分布式存储包括 GlusterFS 和 Ceph;也支持较容易使用的主机本地目录 emptyDir, hostPath 和 NFS。
Deployment、ReplicaSet、Replication Controller
前文说了Master节点中包涵组件Controller Manager,其中具体的一些控制器就包含了Deployment、ReplicaSet、Replication Controller三者,它们相当于一个状态机,用来控制pod的具体状态和行为。
ReplicaSet、Replication Controller
先说Replication Controller,简称
RC
。RC
保证在同一时间能够运行指定数量的Pod副本,保证Pod总是可用。如果实际Pod数量比指定的多就结束掉多余的,如果实际数量比指定的少就启动缺少的。当Pod失败、被删除或被终结时RC
会自动创建新的Pod来保证副本数量。所以即使只有一个Pod也应该使用RC
来进行管理。ReplicaSet,简称
RS
,随着Kubernetes的发展,官方已经推荐我们使用RS
和Deployment
来代替RC
了,RS
对象一般不单独使用,而是作为 Deployment 的理想状态参数使用。目前RS和RC唯一的一个区别就是RC
只支持基于等式的selector
(env=dev或environment!=qa),但RS
还支持基于集合的selector
(version in (v1.0, v2.0)),这对复杂的运维管理就非常方便了。Deployment
Deployment
同样也是Kubernetes
系统的一个核心概念,主要职责和RC
一样的都是保证Pod
的数量和健康,二者大部分功能都是完全一致的,我们可以看成是一个升级版的RC
控制器。除了RC
所包含的功能外,Deployment
还具有以下特性:- 事件和状态查看:可以查看
Deployment
的升级详细进度和状态 - 回滚:当升级
Pod
的时候如果出现问题,可以使用回滚操作回滚到之前的任一版本 - 版本记录:每一次对
Deployment
的操作,都能够保存下来,这也是保证可以回滚到任一版本的基础 - 暂停和启动:对于每一次升级都能够随时暂停和启动
- 事件和状态查看:可以查看
Deployment和ReplicaSet关系
可能看到这,有人会问既然都差不多,有了ReplicaSet为什么还要搞个Deployment对象。两者大概结构如下图:
我们拿滚动升级一个服务的场景来说明,滚动升级一个服务,实际是创建一个新的
RS
,然后逐渐将新RS
中副本数增加到理想状态,将旧RS
中的副本数减小到 0 的复合操作;这样一个复合操作用一个RS
是不太好描述的,所以用一个更通用的Deployment
来描述。我个人的理解,举个不恰当的例子,类似领域模型中的贫血模型和充血模型差不多,RS对象更多像贫血模型,只保留了属性。而
Deployment
对象包含了属性和行为,适用性更广。官方也是强烈建议我们使用Deployment
和RS
来管理Pod。
Service
官方文档中 Service 的定义:
将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
使用 Kubernetes,您无需修改应用程序即可使用不熟悉的服务发现机制。Kubernetes 为 Pods 提供自己的 IP 地址,并为一组 Pod 提供相同的 DNS 名, 并且可以在它们之间进行负载均衡。
可以发现,Service
对象提供了2种能力:让Pod能够被服务发现和被负载均衡。为什么这么说呢,因为Service
对象本身并不干这两件事情。Service
是一种抽象的对象,它定义了一组Pod
的逻辑集合和一个用于访问它们的策略,其实这个概念和微服务非常类似。
为什么需要Service对象?
RC、RS 和 Deployment 只是保证了支撑服务的微服务 Pod 的数量,但是没有解决如何访问这些服务的问题。Pod 是有生命周期的。它们可以被创建,而且销毁之后不会再启动。如果您使用 Deployment 来运行您的应用程序,则它可以动态创建和销毁 Pod。每个 Pod 都有自己的 IP 地址,但是在 Deployment 中,在同一时刻运行的 Pod 集合可能与稍后运行该应用程序的 Pod 集合不同,因此不能以确定的 IP 和端口号提供服务。
Service 对象定义了一组
Pod
的逻辑集合和一个用于访问它们的策略,在 Kubernetes 集群中,客户端需要访问的服务就是 Service 对象。每个 Service 会对应一个集群内部有效的虚拟 IP,集群内部通过虚拟 IP 访问一个服务。
Job/Cronjob
我们在日常的工作中经常都会遇到一些需要进行批量数据处理和分析的需求,当然也会有按时间来进行调度的工作,在我们的Kubernetes
集群中为我们提供了Job
和CronJob
两种资源对象来应对我们的这种需求。Job
负责处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod
成功结束。而CronJob
则就是在Job
上加上了时间调度。
Namespace
Namespace 为 Kubernetes 集群提供虚拟的隔离作用,Kubernetes 集群初始有两个命名空间,分别是默认命名空间 default 和系统命名空间 kube-system,除此以外,管理员可以可以创建新的命名空间满足需要。
前文提到的概念都是为了服务 Pod 的,而 namespace 则是为了服务整个 Kubernetes 集群的。是为了把一个 Kubernetes 集群划分为若干个资源不可共享的虚拟集群而诞生的。
其他
其他还有一些核心资源对象,不过貌似对下一步集群部署实践没什么太大影响,后续再补充吧。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。