其实 k8s 得概念并不是很难。基础就是 master、node两个概念。k8s 其实说白了就是一个分布式的管理工具,做容器的管理,那么 k8s 自己附带了监控等等,所以它需要一个 master,其它服务器都是它的 node,而运行的容器都是在 node 中运行。

然后是 pod、service、rc 三个概念。pod 简单来说就是把 n 个容器放进一个箱子里,这个箱子共用一个 ip 和存储,比如 docker 容器要去读写 volume,会通过 pod 的中间件去读写。然后n个pod 组成一个 service 这个概念。

rc 就是 pod 的控制器,通过预先定义的规则来保证 pod 的数量足够,且符合预先设定。

所以整个流程就是比如说有 业务服务 这个service,这个service依赖于core、mysql、redis,那么这三个分别有个单独的pod,pod里有n个容器。

如果现在core是运行在 a node 上,当a发生了故障时,k8s 就会将整个 pod 转移到 b node 上。且根据 rc 中设置的规则自动创建预先设定的数量。

HPA 就是用于控制每个 pod 所使用的系统资源,如 cpu 占用率、内存占用率。

不过 k8s 有个非常诡异的地方,无论是 hpa、rc 在控制 pod 时,都是通过这个 pod 创建时设置的label,也就是标签名字来控制的。我估摸着是历史遗留问题,可能之前加 hpa、rc 之类的功能时为了兼容之前版本所以可以不需要强制设置 pod 的名字。

k8s的网络请求也是非常奇特,用户的请求到达 k8s 最外层的 ip,然后通过一层代理到某个service,service 会由指定的 pod 受理请求,通过负载均衡分发到 pod 里的某个容器中。

因为每个 service 都有个独立的虚拟 ip,所以可以通过虚拟 ip 去调用这个 service。在之前的版本中会将所有 service 的 ip 和端口在创建时塞到系统变量中。因为不优雅,后来改成了 dns 机制,也就是通过一个不能公网访问的域名来指向这个 service 对于的 ip。

有了上面的机制后就衍生了一些工具性质的机制,如 job,job 就是通过某个规则自动生成 n 个 pod 去执行设定的任务。任务完成后销毁 pod。volume 就跟容器自己的 volume 类似,但因为pod 里的容器访问硬盘时,实际上是通过某个中间件访问的,所以 k8s 在这个中间件上提供了一些新的存储支持。除了容器所在宿主的硬盘,还支持远程硬盘、公有云的磁盘、NFS。这个是用于解决,前面说的如果一个 node 突然死翘翘,那么转移 pod 的时候,很多数据库类的 pod 是有依赖存储的,所以可以将东西存储在一个支持分布式的硬盘来解决这个问题。

新问题又来了。比如说ai服务与业务服务都要调用一个模型,正常情况下一个模型可能 5-10G,不可能移动来移动去,所以在 volume 机制上实现了 persistent volume 的共享存储机制,这个任何 node 都可以访问,都可以挂载,这个 node 中所有的 pod 都可以使用。这个机制支持了大量的国外的公有云服务的云硬盘,国内我还没仔细研究。

如果需要共享同一个配置文件,就可以使用 configMap,这个是一个基于上述机制的类似key=value 的一个东西,可以设置映射到存储中的某个文件中,那么一调用 configMap,实际上就是调用存储空间中的某个文件。

k8s 为了解决多租户的问题,比如不同部门都在使用同个 k8s,提出了 namespace 的概念,就是在 service 上面再套一个箱子。不同的用户管理不同的 namespace。