# Kubernetes 核心概念

# Cluster 集群

集群 是由很多节点组成的,可以按需添加更多的阶段。这个节点可以是 物理机虚拟机

每个节点都有一定的 CPU 和 内存 容量。整个 Kubernetes 集群可以抽象看做一个超大的计算机。它的 CPU 和 内存 容量是所有节点 CPU 和 内存 容量的总和。

# Container 容器

Kubernetes 是一个容器调度,编排平台。容器时 Kubernetes 的一个基本概念。

容器有两点关键信息,一个是打包机制,背后是由容器镜像(Image)机制来实现的。另一个是隔离,背后是由Linux NamespaceLinux Cgroupsrootfs这些机制来实现的。

一个“容器”,实际上是一个由 Linux NamespaceLinux Cgroupsrootfs 三种技术构建出来的 进程的隔离环境

容器经常被形象的比喻为集装箱,集装箱是用来打包和运输货物的。而且可以相互隔离。

软件容器是用来打包和运行应用的,里面可以跑各种语言栈的应用,容器之间通过轻量级的机制,Linux NamespaceLinux Cgroupsrootfs 进行隔离。

从宿主机的操作视角来看容器是一个一个的进程。从容器内部视角来看,它感觉自己就是一个完整的操作系统。有自己的文件系统,网络,CPU和内存等资源。

容器时镜像的运行时实例,镜像是OS文件系统,加上应用文件,加上依赖的一个打包。镜像可以任务是容器的一个模板。

# Pod

Kubernetes 并没有直接的调度容器,而是封装了一个叫做 Pod 的概念。

Pod 是一组紧密关联的容器集合,它们共享 IPC、Network 和 UTS namespace,是 Kubernetes 调度的基本单位。

Pod 内的多个容器共享网络和文件系统,可以通过 进程间通信文件共享 这种简单高效的方式组合完成服务。

Pod 在英文中是豌豆荚的意思。一个 Pod 中可以运行一个或多个容器。它们共享 Pod 的文件系统,以及网络。每个 Pod 有独立的 IP。Pod 中的容器共享这个 IP 和端口空间。并且可以通过 localhost 相互访问。

绝大部分情况下,一个 Pod 里面只运行一个应用容器。

Kubernetes 并没有直接的调度容器,而是增加了这个 Pod 的封装。一方面,是考虑了需要辅助容器的场景。比方说,有些需要 sidecar 的场景。另外一方面,是考虑可以替换使用不同的容器技术,比如 Docker 容器。

Pod

# ReplicaSet 副本集

通常处出于高可用性的考虑,一个应用发布时不会只发布一个 Pod,而是会发布多个 Pod 实例。

ReplicaSet 副本集,就是和一个应用的一组 Pod 相对应的概念。

它是 Kubernetes 中的一种 控制器

它可以通过模板,一般是 YAML 或者是 json 文件规范的模板。来定义某个应用,容器的镜像,端口,副本数量,点火,健康检查机制,环境变量,volume挂载等等的相关信息。应用运行过程中,ReplicaSet 会监控和维护 Pod 的数量,确保实际状态和期望状态是 最终一致 的。

# Service 服务

Pod 在 Kubernetes 中是一个 ephemeral(短暂的) 的概念。中文理解就是不固定的,这个 Pod 有可能随时挂掉或者重启。有可能是预期的或非预期的。相应的 Pod 的 IP 就会变。如果,一个服务的 IP 随时会变,不固定,那么服务的消费方寻址就会很困难。

Kubernetes 中引入了 Service 这个抽象来解决这个问题。简单讲 Service 屏蔽了应用的IP寻址和负载均衡这些细节。

Service 是对一组提供相同功能的 Pods 的抽象,并为它们提供一个统一的入口。

借助 Service,应用可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级。

Service 通过标签(label-selector)来选取服务后端,一般配合 Replication Controller 或者 Deployment 来保证后端容器的正常运行。这些匹配标签的 Pod IP 和端口列表组成 endpoints,由 kube-proxy 负责将服务 IP 负载均衡到这些 endpoints 上。

# Service 类型

Service 有四种类型:

  • ClusterIP:默认类型,自动分配一个仅 cluster 内部可以访问的虚拟 IP
  • NodePort:在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过 <NodeIP>:NodePort 来访问该服务。如果 kube-proxy 设置了 --nodeport-addresses=10.240.0.0/16(v1.10 支持),那么仅该 NodePort 仅对设置在范围内的 IP 有效。
  • LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到 <NodeIP>:NodePort
  • ExternalName:将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)。需要 kube-dns 版本在 1.7 以上。

另外,也可以将已有的服务以 Service 的形式加入到 Kubernetes 集群中来,只需要在创建 Service 的时候不指定 Label selector,而是在 Service 创建好后手动为其添加 endpoint。

# Deployment 发布

ReplicaSet 可以认为是一种基本的发布机制。通过 ReplicaSet 可以实现基本的应用发布。也可以实现高级的发布功能,比如说,金丝雀,蓝绿,滚动发布等。但是通过 ReplicaSet 实现这些高级发布功能是操作比较复杂和繁琐的。为了简化这些高级发布功能,Kubernetes 在 ReplicaSet 的基础上,引入了 Deployment 这个概念。

简单说,Deployment 是用来管理 ReplicaSet的,从而可以实现金丝雀,蓝绿,滚动这些高级发布机制的。

Deployment 和 Service 是和应用发布相关的两个最重要的概念。也是发布过程中经常使用的两个概念。

我们发布应用时,所要编辑的发布描述文件里面主要就是 Deployment 和 Service 规范。

Deployment 是基于 ReplicaSet 之上的概念,发布应用时 Deployment 会创建 ReplicaSet。ReplicaSet根据规范创建应用的 Pod 实例。并且维护和保证实例数量。服务升级时,Deployment 会创建 ReplicaSet,创建新的 Pod 实例,如果一个 Pod 实例运行成功,则会删除一个旧的实例。如果某个 Pod 实例运行失败,则会回退版本。从而调度实现滚动发布以及发布回退功能。

Service 可以实现服务间相互寻地址。Kubernetes 集群内部的 Clients 通过 Service 间接访问目标应用 Pod。Kubernetes 集群外部的 Client,如果要访问集群内部应用的 Pod,也是通过 Service 间接访问的。

# ConfigMap/Secret

微服务上线时,通常需要设置一些可变配置。这些配置针对不同的环境,对应的配置值也可能是不同。

这些配置有些是在启动期间,一次性配置好的。比如说,数据库连接信息。还有一些配置可以在应用运行期间动态调整,比如说,缓存过期时间TTL等。

所以微服务需要配置中心的支持,实现针对不同的灵活的动态配置。

Kubernetes 内置支持微服务配置,对应的概念叫 ConfigMap。开发人员将配置信息填写在 ConfigMap 中,Kubernete 支持将 ConfigMap 中的配置以 环境变量 的形式注入到 Pod 中。从而使 Pod 中的应用以 环境变量 的形式去访问这些配置。此外,ConfigMap 也支持以 Volume(存储卷)的形式,挂载到 Pod 当中,从而使 Pod 中的应用以 本地配置文件 的形式去访问这些配置。

有些配置是涉及敏感数据的,比如,用户名,密码,安全证书等。Kubernetes 通过 Secret 的概念。支持敏感数据的配置。Secret 可以被认为是一种特殊的 Config。它提供更安全配置存储和访问机制。

# DaemonSet

顾名思义,DaemonSet 的主要作用,是让你在 Kubernetes 集群里,运行一个 Daemon Pod 常驻守护进程。 所以,这个 Pod 有如下三个特征:

  • 这个 Pod 运行在 Kubernetes 集群里的每一个节点(Node)上;
  • 每个节点上只有一个这样的 Pod 实例;
  • 当有新的节点加入 Kubernetes 集群后,该 Pod 会自动地在新节点上被创建出来;而当旧节点被删除后,它上面的 Pod 也相应地会被回收掉。

常见使用场景,日志采集,监控等。

# Volume

存储卷抽象。可以简单理解为磁盘文件存储。可以是节点本地文件存储,也可以是远程存储。

挂载 mount 之后,Volume 成为对应 Pod 的一部分,Pod 销毁 Volume 也销毁,但是支持 Volume 背后的存储可以依然存储。

# Persistent Volume(PV)

PV 描述的,是持久化存储数据卷。

如果 Volume 只使用节点本地存储,那么下次应用启动 Pod 时如果换了一个节点,那么相应的这个文件存储就不存在了。

Persistent Volume(PV),是一种高级的存储资源的抽象。它可以对接各种云存储。一般由集群管理员统一配置。如果把 Kubernetes 集群看做一个超大计算机,那么 PV 就可以看做可以灵活插到这台超大计算机上的超大磁盘。

使用 PV 挂载了 Volume,那么应用 Pod 即使重启了,Volume 上的数据也不会丢失。

# Persistent Volume Claim(PVC)

PVC 描述的,则是 Pod 所希望使用的持久化存储的属性。

PVC 是应用申请 PV 的时候,需要填写的规范。包括磁盘大小,类型等等。

3

应用通过 PVC 去申请 PV 资源,然后以 Volume 的形式挂载到 Pod 当中。PV 和 PVC 的引入,使得 Volume 和具体的物理存储可以进一步的解耦。

# StatefulSet

StatefulSet 是支持有状态应用的一种发布机制,比如说 Mysql 数据库,Redis缓存的发布等。它跟 ReplicaSet 是一个相对的概念。ReplicaSet支持无状态应用的发布。

# Job

支持运行一次就结束的离线任务。

# CronJob

支持周期性运行的离线任务。

# Namespace

Namespace 是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的 pods, services, ReplicaSet 和 deployments 等都是属于某一个 namespace 的(默认是 default),而 node, persistentVolumes 等则不属于任何 namespace。

# Label

Label 是识别 Kubernetes 对象的标签,以 key/value 的方式附加到对象上(key 最长不能超过 63 字节,value 可以为空,也可以是不超过 253 字节的字符串)。

Label 不提供唯一性,并且实际上经常是很多对象(如 Pods)都使用相同的 label 来标志具体的应用。

Label 定义好后其他对象可以使用 Label Selector 来选择一组相同 label 的对象(比如 ReplicaSet 和 Service 用 label 来选择一组 Pod)。Label Selector 支持以下几种方式:

  • 等式,如 app=nginxenv!=production
  • 集合,如 env in (production, qa)
  • 多个 label(它们之间是 AND 关系),如 app=nginx,env=test

# Annotations

Annotations 是 key/value 形式附加于对象的注解。不同于 Labels 用于标志和选择对象,Annotations 则是用来记录一些附加信息,用来辅助应用部署、安全策略以及调度策略等。比如 deployment 使用 annotations 来记录 rolling update 的状态。

# 总结

概念 作用
Cluster 超大计算机抽象,由节点组成(物理机或虚拟机)
Container 应用打包,运行在容器内
Pod K8s基本调度单位
ReplicaSet 创建和管理Pod,支持无状态应用
Service 应用Pods的访问点,屏蔽IP寻址和负载均衡
Deployment 管理ReplicaSet,支持滚动,蓝绿,金丝雀等高级发布机制
ConfigMap/Secret ConfigMap普通配置,Secret敏感数据配置
DaemonSet 保证每个节点有且只有一个Pod,常用于日志,监控等
Volume 可装载磁盘文件存储
Persistent Volume(PV)/Persistent Volume Claim(PVC) 超大磁盘存储对象抽象和分配机制
StatefulSet 类似ReplicaSet,但支持有状态应用,如MySql,Redis等
Job 运行一次就结束的离线任务
CronJob 周期性运行的离线任务
Namespace 对一组资源和对象的抽象集合
Label 识别 Kubernetes 对象的标签,以 key/value 的方式附加到对象上,用于标志和选择对象
Annotations 以 key/value 形式附加于对象的注解,用来记录一些附加信息

# 参考

更新时间: 9/21/2020, 12:00:45 AM