在 Kubernetes 完成对 Pod 的调度后,下一步就需要负责将这个调度成功的 Pod 在宿主机上创建起来,同时把 Pod 对应的各个容器启动起来。这些功能的实现正是 kubelet 这个核心组件的任务。
在 Kubernetes 社区里,与 kubelet 以及容器运行时管理相关的内容都属于 SIG-Node 的范畴。SIG-Node 以及 kubelet 其实是 Kubernetes 整套体系里非常核心的一个部分,毕竟它们才是 Kubernetes 这个容器编排与管理系统与容器打交道的主要方式。而 kubelet 这个组件本身也是 Kubernetes 里面第二个不可被替代的组件(第一个不可被替代的组件当然是 kube-apiserver)。也就是说,无论如何都不建议用户对 kubelet 的代码进行大量的改动,保持 kubelet 跟上游基本一致的重要性就跟保持 kube-apiserver 跟上游一致是一个道理。
上篇文章详细介绍了 PV、PVC 持久化存储体系在 Kubernetes 项目中的设计和实现原理。而在持久化存储领域,用户呼声最高的定制化需求,莫过于支持“本地”持久化存储了。也就是说,用户希望 Kubernetes 能够直接使用宿主机上的本地磁盘目录,而不依赖于远程存储服务,来提供“持久化”的容器 Volume。这样做的好处很明显,由于这个 Volume 直接使用的是本地磁盘,尤其是 SSD 盘,它的读写性能相比于大多数远程存储来说,要好得多。这个需求对本地物理服务器部署的私有 Kubernetes 集群来说非常常见。所以,Kubernetes 在 v1.10 之后,就逐渐基于 PV、PVC 体系实现了这个特性。这个特性的名字叫作:Local Persistent Volume。
不过,首先需要明确的是,Local Persistent Volume 并不适用于所有应用。事实上,它的适用范围非常固定,比如:高优先级的系统应用,需要在多个不同节点上存储数据,并且对 I/O 较为敏感。典型的应用包括:分布式数据存储比如 MongoDB、Cassandra 等,分布式文件系统比如 GlusterFS、Ceph 等,以及需要在本地磁盘上进行大量数据缓存的分布式应用。
其次,相比于正常的 PV,一旦这些节点宕机且不能恢复时,Local Persistent Volume 的数据就可能丢失。这就要求使用 Local Persistent Volume 的应用必须具备数据备份和恢复的能力,允许用户把这些数据定时备份在其他位置。
上篇文章介绍 PV 和 PVC 的时候,提到 PV 这个对象的创建一般是由运维人员完成的。但是,在大规模的生产环境里,这其实是一个非常麻烦的工作。这是因为,一个大规模的 Kubernetes 集群里很可能有成千上万个 PVC,这就意味着运维人员必须得事先创建出成千上万个 PV(PV 与 PVC 是一一对应的)。更麻烦的是,随着新的 PVC 不断被提交,运维人员就不得不继续添加新的、能满足条件的 PV,否则新的 Pod 就会因为 PVC 绑定不到 PV 而失败。在实际操作中,这几乎没办法靠人工做到。所以,Kubernetes 为我们提供了一套可以自动创建 PV 的机制,即:Dynamic Provisioning。相比之下,前面人工管理 PV 的方式就叫作 Static Provisioning。
我们知道,容器化一个应用比较麻烦的地方,莫过于对其“状态”的管理。而最常见的“状态”,又莫过于存储状态。因此,Kubernetes 存储篇系列文章主要用来剖析 Kubernetes 项目处理容器持久化存储的核心原理。
上篇文章讲解了将 Service 暴露给外界的三种方法。其中有一个叫作 LoadBalancer 类型的 Service,它会为你在 Cloud Provider(比如:Google Cloud 或者 OpenStack)里创建一个与该 Service 对应的负载均衡服务。但是,由于每个 Service 都要有一个负载均衡服务,所以这个做法实际上既浪费成本又高。
用户其实更希望看到 Kubernetes 为他们内置一个全局的负载均衡器。然后通过用户访问的 URL,把请求转发给不同的后端 Service。这种全局的、为了代理不同后端 Service 而设置的负载均衡服务,就是 Kubernetes 里的 Ingress 服务。所以,Ingress 的功能其实很容易理解:所谓 Ingress,就是 Service 的“Service”。
上一篇文章介绍了 Service 机制的工作原理,我们可以发现这样一个事实:Service 的访问信息在 Kubernetes 集群之外,其实是无效的。这其实也容易理解:所谓 Service 的访问入口,其实就是每台宿主机上由 kube-proxy 生成的 iptables 规则,以及 kube-dns 生成的 DNS 记录。而一旦离开了这个集群,这些信息对用户来说,也就自然没有作用了。所以,在使用 Kubernetes 的 Service 时,一个必须要面对和解决的问题就是:如何从外部(Kubernetes 集群之外),访问到 Kubernetes 里创建的 Service?