命令式API
比如:
先kubectl create,再replace的操作,我们称为命令式配置文件操作
kubectl replace的执行过程,是使用新的YAML文件中的API对象,替换原有的API对象;而kubectl apply,则是执行了一个对原有API对象的PATCH操作。
kube-apiserver在响应命令式请求(比如,kubectl replace)的时候,一次只能处理一个写请求,否则会有产生冲突的可能。而对于声明式请求(比如,kubectl apply),一次能处理多个写操作,并且具备Merge能力。
什么是API对象
要快速掌握 Kubernetes (k8s) 中 API 对象的核心知识,以下是最重要的20%,这将帮助你理解和操作80%的 k8s 功能:
-
API对象的概念:
- API对象是 k8s 集群中的
管理操作单元
,每支持一项新功能,就会引入对应的API对象。 - API对象具有三大类属性:
元数据(metadata)、规范(spec)和状态(status)
。- 元数据(metadata):用于标识API对象,包括namespace、name和uid,以及用于匹配不同对象的标签(labels)。
- 规范(spec):描述对象的
期望状态
(Desired State),即用户希望对象所具有的特征。 - 状态(status):描述对象的
实际状态
(Actual State),由 Kubernetes 系统提供和更新。
- API对象是 k8s 集群中的
-
API对象的管理方式:
- 使用
kubectl
工具,可以通过命令式命令、命令式对象配置和声明式对象配置三种方式管理API对象。
- 使用
-
标签(Label)和选择器(Selector):
- 标签是识别 Kubernetes 对象的标签,以 key/value 的方式附加到对象上。
- 选择器用于选择具有特定标签的一组对象。
-
API 组和版本:
- Kubernetes API 遵循 OpenAPI 规范,并以端点
/openapi/v2
提供 API 规范。 - API 组和版本是 Kubernetes API 的重要概念,不同的功能模块被划分为不同的 API 组。
- Kubernetes API 遵循 OpenAPI 规范,并以端点
-
核心API对象:
- Pod:k8s中的基本部署单元,可以包含一个或多个容器。
- Node:k8s中的工作节点,负责运行Pod。
- Master:集群控制节点,负责整个集群的管理和控制。
- Deployment:用于描述应用的部署状态,包括应用的副本数、更新策略等。
- Service:定义了一种访问Pod的方式,可以是ClusterIP、NodePort、LoadBalancer等。
-
API 交互:
- Kubernetes 支持
application/json
和application/yaml
媒体类型用于请求和响应。 - 客户端可以通过设置
Accept
头部来请求服务器以表格形式返回对象。
- Kubernetes 支持
掌握这些核心概念和操作,将为你在 Kubernetes 中管理复杂的应用和服务打下坚实的基础。
Istio项目
-
困难
当一个Pod或者任何一个API对象被提交给APIServer之后,总有一些“初始化”性质的工作需要在它们被Kubernetes项目正式处理之前进行。比如,自动为所有Pod加上某些标签
“初始化”操作的实现,借助的是一个叫作Admission的功能。它其实是Kubernetes项目里一组被称为Admission Controller的代码,可以选择性地被编译进APIServer中,在API对象创建之后会被立刻调用到
如果你现在想要添加一些自己的规则到Admission Controller,就会比较困难。因为,这要求重新编译并重启APIServer -
Istio流程
在它对应的API对象里自动加上Envoy容器的配置
编写一个用来为Pod“自动注入”Envoy容器的Initializer
ConfigMap的data部分,正是一个Pod对象的一部分定义
Initializer要做的工作,就是把这部分Envoy相关的字段,自动添加到用户提交的Pod的API对象
在Initializer更新用户的Pod对象的时候,必须使用PATCH API来完成
Istio将一个编写好的Initializer,作为一个Pod部署在Kubernetes中
事先编写好的“自定义控制器”(Custom Controller)
Kubernetes还允许你通过配置,来指定要对什么样的资源进行这个Initialize操作:InitializerConfiguration
这也就意味着,当你在Initializer里完成了要做的操作后,一定要记得将这个metadata.initializers.pending标志清除掉。这一点,你在编写Initializer代码的时候一定要非常注意