个人在入门k8s时的一些简单的笔记

Kubernetes,简称k8s,是云原生生态的基石,是CNCF技术栈的核心。

注: CNCF即为云原生计算基金会,是一个开源的软件基金会,致力于云原生技术的普及及可持续发展。许多有名的项目都托管在这个社区当中,包括Docker、Kubernetes。

Kubernetes脱骨于Google的Borg系统,而Borg承载了Google公司整个基础设施的核心依赖,k8s在Borg体系的指导之下,在众多容器编排工具中脱颖而出。

为什么需要容器编排

一个Docker容器本质上是一个进程,当然处理不了太多的事情,在一个大型项目当中,可能会有成千上万个容器共同工作,如何处理容器之间复杂的关系让它们协同起来,是一个很棘手的问题。

于是类似于k8s这样的容器编排工具就应运而生。

用户的期望

作为用户,我们已经有了应用的容器镜像,我们希望k8s这样的工具,给我们: 在一个给定的集群上运行这个应用,并且提供路由网关、水平扩展、监控、备份、灾难恢复等一系列运维能力。

Kubernetes架构

pPaWY9K.png

图源自[1],展现了Kubernetes的全局架构。

k8s由Master和Node两种节点组成,分别是控制节点和计算节点。Master节点中有三个独立组件,分别是负责API服务的kube-apiserver、负责调度的kube-scheduler,以及负责容器编排的kube-controller-manager。整个集群的持久化数据,由kube-apiserver处理后保存在etcd中。
其中etcd是一个分布式的、高可用的、一致的KV存储数据库,基于raft共识算法实现,主要用于共享配置和服务发现。

计算节点上最核心的地方,是一个名为kubelet的组件,主要负责同容器运行时交互。这种交互依赖一个称作CRI(container runtime interface)的远程调用接口,这个接口定义了容器运行时的各项核心操作,比如启动一个容器需要的所有参数。

而容器运行时则通过OCI这个容器运行时规范同底层Linux系统进行交互,即把CRI请求翻译成对Linux系统的调用。

kubelet还通过gRPC协议同一个叫做Device Plugin的插件进行交互,这个插件是管理GPU等宿主机物理设备的主要组件。

kubelet还通过CNI(container networking interface)和CSI(container storage interface)接口调用网络插件和存储插件为容器配置网络和持久化存储。

Kubernetes核心能力与项目定位

在大规模集群中的各种任务之间运行,实际上存在各种各样的关系。这些关系的处理才是作业编排和管理系统最困难的地方。

这句话道出了Kubernetes核心能力和项目定位,来自于Borg论文中。

任务与任务之间的关系,诸如Web应用与数据库之间的访问关系,负载均衡器和后端服务之间的代理关系等等。

在容器之前,使用虚拟机来处理这种关系,将可能发生通信的任务部署在同一台虚拟机中,是”粗粒度”的,不仅如此,还需要手动维护守护进程。

而有了容器技术,可以将服务放在独立的容器中,容器可以被调度到集群中的任何一台机器上,它是”细粒度”的。

如何编排 & 调度呢?

Kubernetes以统一的方式抽象底层基础设施能力(比如计算、存储、网络),定义任务编排的各种关系(比如亲密关系、访问关系、代理关系),将这些抽象以声明式API的方式对外暴露,从而允许平台构建者基于这些抽象进一步构建自己的PaaS乃至任何上层平台。

Kubernetes对容器间的访问进行了抽象和分类,它总结出了一类常见的紧密交互的关系,即这些任务之间需要非常频繁地交互和访问,或者它们会直接通过本地文件交换信息。

在常规环境中,这些应用会被部署在同一台机器上,通过localhost进行通信,通过本地磁盘目录交换文件。

而在Kubernetes中,这些容器会被划分为一个Pod,Pod中的容器共享同一个Network Namespace、同一组Volumn,从而实现高效交换信息。Pod是Kubernetes中最基础的一个对象。

但是。对于容器来说,它的IP地址是不固定的,一个应用如何找到另一个应用的Pod呢?

Kubernetes的做法是给Pod绑定一个Service服务,而Service服务声明的IP地址等信息是固定不变的。Service服务作为Pod的代理入口,代替Pod对外暴露一个固定的网络地址。Service负责相应Pod的IP地址、端口等信息的自动更新、维护。

如果我们希望一次启动多个应用的实例,需要使用Deployment这个Pod的多实例管理器。

Secret是保存在etcd中的键值对数据,可以将授权信息(比如Web访问数据库时需要用户名和密码)存放在Secret对象中,Kubernetes就会在Web应用的Pod启动时,自动把Secret里的数据以Volumn的方式挂载到容器里。

声明式API

如何使用Kubernetes?

首先,通过一个任务编排对象,比如Pod、Job、CronJob等,描述你试图管理的应用;

然后,为它定义一些运维能力对象,比如Service、Ingress、Horizontal Pod Autoscaler(自动水平扩展器)等,这些对象会负责具体的运维能力侧功能。

这种使用方法就是”声明式API”。这种API对应的编排对象和服务对象,都是Kubernetes项目中的API对象。

题外话: 命令式API告诉系统它需要做什么,需要怎么做;而声明式API告诉系统我们想要什么,系统如何去完成是系统的事。声明式API及其优势可以查看参考文献[3].

声明式API是Kubernetes最核心的设计理念,正因为有了它,我们基于Kubernetes构建的上层平台才有了一致的编程范式和交互编程界面,才使得今天整个云原生生态中诞生了如此多的Kubernetes插件能力和扩展。

Kubernetes的使用

首先按照格式编写YAML文件,随后执行:

kubectl create -f xxx.yaml

这样对应的容器就启动了。

参考文献

[1] 张磊. 深入剖析Kubernetes[M]. 第1版. 人民邮电出版社, 2021.3.
[2] Hu先生的Linux. ETCD介绍—etcd概念及原理方面分析[EB/OL]. [2023-08-29]. https://zhuanlan.zhihu.com/p/405811320.
[3] Docker_. 为什么说声明式API比命令式API更优雅?[EB/OL]. [2023-08-29]. https://blog.csdn.net/M2l0ZgSsVc7r69eFdTj/article/details/122890922.

版权声明: 如无特别声明,本文版权归 月梦の技术博客 所有,转载请注明本文链接。

(采用 CC BY-NC-SA 4.0 许可协议进行授权)

本文标题:《 浅谈Kubernetes 》

本文链接:https://ymiir.netlify.app//%E4%BA%91%E5%8E%9F%E7%94%9F/%E6%B5%85%E8%B0%88k8s.html

本文最后一次更新为 天前,文章中的某些内容可能已过时!