K8S API概述

可参阅:kubernetes.io/zh-cn/docs/…

Kubernetes API是Kubernetes操控平面的核心。它是一组REST API,用于与Kubernetes中的各种目标进行交互,如Pods、Namespaces、ConfigMaps和Events等。经过这些API,能够查询和操作Kubernetes中API目标的状况。

API server是Kubernetes集群中的一个组件,它公开了这些REST API。Kubernetes中的各种组件,包含kubectl指令行东西、kubeadm等东西,都经过调用这些API来履行操作。

除了运用kubectl等东西之外,也能够直接运用REST调用来拜访API。假如正在编写运用Kubernetes API的应用程序,请考虑运用其中一个客户端库。

完整的API详细信息都运用OpenAPI进行文档化,这使得运维开发人员能够很容易地了解API的功用和运用方法。

上篇:运维人员不得不看的K8S API入门实战,呕心沥血整理得又臭又长,有人看吗

OpenAPI 标准

Kubernetes OpenAPI 标准实际上只有一种,它是依据 OpenAPI 3.0 标准的。之前版别的 Kubernetes API 运用的是 Swagger 2.0 标准,但现在现已升级到了 OpenAPI 3.0 标准。

需求留意的是,尽管 OpenAPI 3.0 标准是 Swagger 2.0 标准的继承者,但它们之间有一些重要的区别,如参数、呼应、恳求体和安全等方面的界说方法都有所不同。因而,在运用 OpenAPI 标准时需求留意版别兼容性。接下来,别离了解一下V2和V3。

OpenAPI V2

Kubernetes API服务器供给了一个聚合的 OpenAPI v2 标准,经过拜访 /openapi/v2 端点获取。这个标准包含了一切的API组的界说,以及每个API组的一切API的界说,使得运维开发人员能够清楚地了解Kubernetes API的结构和功用。

经过在HTTP恳求头中指定不同的呼应格局,运维开发人员能够取得不同格局的OpenAPI标准文档。下表列出了可用的恳求头和呼应格局:

头部 可选值 阐明
Accept-Encoding gzip 不指定此头部也是能够的
Accept application/com.github.proto-openapi.spec.v2@v1.0+protobuf 首要用于集群内部
application/json 默许值
* 供给application/json

经过运用这些恳求头,开发人员能够获取他们所需的格局化的OpenAPI标准文档,以便在应用程序中进行处理和解析。

Kubernetes的API运用Protobuf作为序列化格局进行内部通信。这种序列化格局有助于减少网络传输的数据量和进步通信的功率。在Kubernetes中,每个API目标都有一个对应的Protobuf界说文件。这些文件描绘了目标的结构和字段。Kubernetes还供给了运用这些Protobuf界说文件生成客户端和服务器代码的东西,以便开发人员能够轻松地运用Kubernetes API。除了Protobuf之外,Kubernetes还支撑运用其他序列化格局进行通信,例如JSON和YAML。这些格局更易于阅读和编写,并且一般用于与外部系统的集成。不过,在集群内部通信时,Protobuf仍然是最常用的序列化格局。

想进一步了解 Kubernetes Protobuf 序列化可参阅:github.com/kubernetes/…

OpenAPI V3

OpenAPI V3是Kubernetes支撑的一种API描绘格局。从Kubernetes v1.27版别开端,这个功用现已被安稳支撑。

Kubernetes供给了一个名为 /discovery/v3 的端点来展示一切可用的API组和版别列表。这个端点只回来JSON格局的数据。这些API组和版别会以特定的格局呈现:

{
"paths":{
...,
"api/v1":{
"serverRelativeURL":"/openapi/v3/api/v1?hash=CC0E9BFD992D8C59AEC98A1E2336F899E8318D3CF4C68944C3DEC640AF5AB52D864AC50DAA8D145B3494F75FA3CFF939FCBDDA431DAD3CA79738B297795818CF"
},
"apis/admissionregistration.k8s.io/v1":{
"serverRelativeURL":"/openapi/v3/apis/admissionregistration.k8s.io/v1?hash=E19CC93A116982CE5422FC42B590A8AFAD92CDE9AE4D59B5CAAD568F083AD07946E6CB5817531680BCE6E215C16973CD39003B0425F3477CFD854E89A9DB6597"
},
....
}
}

为了进步客户端缓存功率,这些相对URL指向不可变的OpenAPI描绘信息。为此,API服务器还设置了适当的HTTP缓存标头(将Expires设置到未来的1年,将Cache-Control设置为不可变)。当运用过时的URL时,API服务器会将其重定向到最新的URL。

Kubernetes API服务器在 /openapi/v3/apis//?hash= 端点为每个Kubernetes组版别发布一个OpenAPI v3标准。

接受的恳求标头请参阅下表:

头部 可选值 阐明
Accept-Encoding gzip 不供给此头部也是可接受的
Accept application/com.github.proto-openapi.spec.v3@v1.0+protobuf 首要用于集群内部运用
application/json 默许
* 以 application/json 形式回来

API参阅

API 端点、资源类型以及示例可参阅: kubernetes.io/zh-cn/docs/…

恳求API经历的阶段

可参阅:kubernetes.io/zh-cn/docs/…

用户能够运用kubectl、客户端库或经过进行REST恳求来拜访Kubernetes API。不管是人类用户仍是Kubernetes服务账户,都能够被授权拜访API。当恳求到达API时,它会经过几个阶段,如下图所示:

图片

衔接和证书:

  • API Server默许在6443端口上进行监听,也能够修正。
  • 拜访API,运用TLS建立衔接。
  • API Server证书,能够是私有CA、也能够是公认CA。

上图进程的认证进程:

  1. 恳求API时,会和APIServer建立TLS衔接。
  2. 进入身份认证模块(Authentication),验证拜访API的用户是否合法,认证不经过则回来401。
  3. 进入鉴权模块(Authorization),确认该用户是否具有拜访某个资源或履行某个操作的权限, 假如现有策略声明该用户有权完成恳求的操作,则鉴权经过。
  4. 进入准入操控器(Admission Control),履行验证和/或改变操作。
  5. 经过一切准入操控器后,再检查对应的API目标,然后将其写入目标存储。

鉴权模块阐明:鉴权模块的完成有RBAC、ABAC、Node、Webhook。可参阅:kubernetes.io/zh-cn/docs/…

准入操控器阐明:准入操控器会在恳求经过认证和鉴权之后、目标被耐久化之前拦截到达 APIServer的恳求,准入操控进程会运转两个阶段,别离是第1阶段是运转改变准入操控器,第2阶段是运转验证准入操控器。留意了,某些操控器既是改变准入操控器又是验证准入操控器。假如两个阶段之一的任何一个操控器回绝了某恳求,则整个恳求将立即被回绝,并向最终用户回来错误。如要进一步了解准入操控器可参阅:kubernetes.io/zh-cn/docs/…

恳求API之前预备一个一般用户

一切 Kubernetes 集群都有两类用户:

  • 由 Kubernetes 管理的服务账号
  • 一般用户

在实际工作中要调用K8S API,为了增加安全性,建议创立一个专用的一般程序账号。

1. 创立一般用户的私钥

为了让一般用户能够经过认证并调用API,需求履行几个进程。首要,该用户有必要拥有Kubernetes集群签发的证书,然后将该证书供给给Kubernetes API。

可参阅:kubernetes.io/zh-cn/docs/…

#创立一个一般用户的私钥和证书签名恳求(CertificateSigningRequest,CSR)。能够运用OpenSSL东西生成私钥和CSR:
opensslgenrsa-outtantianran.key2048
opensslreq-new-keytantianran.key-outtantianran.csr-subj"/CN=tantianran/O=noblameops"

这里 tantianran 是用户的称号,noblameops 是用户所属的组织。

2. 创立证书签名恳求(CertificateSigningRequest),并提交到Kubernetes集群

将 CSR 提交给 Kubernetes 集群中的证书签名组织 (Certificate Authority, CA) 进行签名。能够运用 kubectl 东西提交 CSR 并获取签名后的证书:

cat<<EOF|kubectlapply-f-
apiVersion:certificates.k8s.io/v1
kind:CertificateSigningRequest
metadata:
name:tantianran
spec:
request:LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ2J6Q0NBVmNDQVFBd0tqRVRNQkVHQTFVRUF3d0tkR0Z1ZEdsaGJuSmhiakVUTUJFR0ExVUVDZ3dLYm05aQpiR0Z0Wlc5d2N6Q0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU1Jc0M0R2JSQ0NJCmE1L2RLenpYc3VtUXVxay9qclZRemJuSmpiVkY5ZVV6bU1OR3drTi9aanRrVU5ZTUNRMkRpY1JIRUJzTFVMTTIKSFhTdkZtV1lUUGN6OEJWOHgvR214YXlWcVNmQTU4aDNtdjJERjhZdFB2aFlVc3hmUVZpUUxFRGFwRXpoV29TcApVN3BwRjJ4YXZjeG9GbDd3emRQWE9YMnhDQXNSQ3pINjB6cG9zSEJiNHBaSGJjYjNyQ1hjdHBnVlFDeklubWRGCjFrNHJncHg5SGsrek4rNzQ1R04vS1dMMWdLcFNhN2YxemdHdXVaT2FrZEhKaldGdCtWYzNFSG90SFQ3V3g1VTEKazV4ZnpuZkk2VlkvN0NTbzR1K2hhSTg2RHBRaXZmdk1OM3ZGeURwOVR2UWVsOFJpZlFiMkxaMnlUYzdEL3hHQQpCWUZhQ25OUjl3a0NBd0VBQWFBQU1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ0hyNmYxd3A0NFd1L1dtczAvCmRFdWswVjJrMElzQzZoOHppbkptN3BHMjlpSFVrVDZNWDNBR3E0WlVZNkVBN3BYa1VDazhsYXFGVjVQTmJoSXkKUTBEUndRdW82WHNqZ1JMQmdZZFNRaU5vVUYrR1ZCSEEyNmZEV3c2VU8zdjErZXVJODlOWXVJbXl4UGtpaE0xYgpyZkNoa1RCeXRBbUxHbVlwOU5OMnBHdDJyTW94cGtDME5PSElWOWdPUnp1Q1h3cytWTE5zS3VSS2diT1hsUVhMCmVOeVd4TGlCR0ZSZ1BsaWpyTnQrdnA1WktHRjV1SEVXYStjZ3NXN1cwZCtoRm9XMlYxczVDZ2ZzdU1IdUNlR3AKMUxSVnZheVJSaDVtekdnTlNrdUpkUTBHdU1lbk5tRGpoSDI1NU5CNVBzdHpTOVBSU1lCVUIvdUdIYi9yVXByWgprOHRECi0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
signerName:kubernetes.io/kube-apiserver-client
expirationSeconds:86400#oneday
usages:
-clientauth
EOF

需求留意的几点:

  • usage 字段有必要是 ‘client auth’

  • expirationSeconds 能够设置为更长(例如 864000 是十天)或许更短(例如 3600 是一个小时)

  • request 字段是 CSR 文件内容的 base64 编码值。 要得到该值,能够履行指令

    cattantianran.csr|base64|tr-d"\n"
    

创立完成后检查一下CSR列表:

[root@k8s-a-masterapi-user]#kubectlgetcsr
NAMEAGESIGNERNAMEREQUESTORREQUESTEDDURATIONCONDITION
tantianran58skubernetes.io/kube-apiserver-clientkubernetes-admin24hPending

3. 批准证书签名恳求(CertificateSigningRequest,简称CSR)

[root@k8s-a-masterapi-user]#kubectlcertificateapprovetantianran
certificatesigningrequest.certificates.k8s.io/tantianranapproved

反之,假如要驳回:

kubectlcertificatedenytantianran

4. 获取证书

从CSR获取证书:

kubectlgetcsr/tantianran-oyaml

证书的内容运用 base64 编码,存放在字段 status.certificate。

从 CertificateSigningRequest 导出颁发的证书:

kubectlgetcsrtantianran-ojsonpath='{.status.certificate}'|base64-d>tantianran.crt

5. 依据RBAC的鉴权形式,创立Role(人物)

在 Kubernetes 中,Role 和 ClusterRole 都是用于授权拜访 Kubernetes API 资源的目标,但它们之间有着不同的效果域。Role 是一个姓名空间效果域的资源,它界说了一个人物,即一组操作权限,能够被颁发给一个或多个用户、服务账户或其他人物,以操控它们在某个特定命名空间内的操作权限。因而,当您创立 Role 时,有必要指定该 Role 所属的命名空间。与之相对,ClusterRole 是一个集群效果域的资源,它界说了一组操作权限,能够颁发给任何命名空间内的用户、服务账户或其他人物。因而,ClusterRole 能够用于授权对整个 Kubernetes 集群的操作权限。需求留意的是,由于 Kubernetes 目标要么是姓名空间效果域的,要么是集群效果域的,因而 Role 和 ClusterRole 的称号不同,以便将它们区别开来。假如您要在特定的命名空间内设置拜访权限,则应该运用 Role。假如您要在整个集群中设置拜访权限,则应该运用 ClusterRole。

创立了证书之后,为了让这个用户能拜访 Kubernetes 集群资源,现在就要创立 Role 和 RoleBinding(鄙人一末节创立) 了。

下面指令将在 rook-ceph 命名空间中创立一个名为 developer 的人物,并为该人物分配一些操作权限。具体来说,该人物将被颁发在该命名空间内创立、获取、列出、更新和删去 pods 资源的权限。

kubectlcreateroledeveloper--verb=create--verb=get--verb=list--verb=update--verb=delete--namespace=rook-ceph--resource=pods
  • kubectl create role developer:创立一个名为 developer 的人物。
  • –verb=create –verb=get –verb=list –verb=update –verb=delete:指定该人物答应的操作权限,即创立、获取、列出、更新和删去。
  • –namespace=rook-ceph:指定该人物所属的命名空间为 rook-ceph。
  • –resource=pods:指定该人物所授权的资源类型为 pods。

对应的yaml如下:

apiVersion:rbac.authorization.k8s.io/v1
kind:Role
metadata:
name:developer
namespace:rook-ceph
rules:
-apiGroups:
-""
resources:
-pods
verbs:
-create
-get
-list
-update
-delete

列出rook-ceph命名空间下的role:

[root@k8s-a-masterapi-user]#kubectlgetroles-nrook-ceph
NAMECREATEDAT
cephfs-external-provisioner-cfg2023-04-03T08:28:33Z
developer2023-04-19T08:10:25Z#这个就是方才创立的
rbd-csi-nodeplugin2023-04-03T08:28:33Z
rbd-external-provisioner-cfg2023-04-03T08:28:33Z
rook-ceph-cmd-reporter2023-04-03T08:28:33Z
rook-ceph-mgr2023-04-03T08:28:33Z
rook-ceph-osd2023-04-03T08:28:33Z
rook-ceph-purge-osd2023-04-03T08:28:33Z
rook-ceph-rgw2023-04-03T08:28:33Z
rook-ceph-system2023-04-03T08:28:33Z

6. 依据RBAC的鉴权形式,创立 RoleBinding (人物绑定)

人物绑定(Role Binding)是将人物中界说的权限赋予一个或许一组用户。 它包含若干 主体(用户、组或服务账户)的列表和对这些主体所取得的人物的引证。 RoleBinding 在指定的姓名空间中履行授权,而 ClusterRoleBinding 在集群规模履行授权。一个 RoleBinding 能够引证同一的姓名空间中的任何 Role。 或许,一个 RoleBinding 能够引证某 ClusterRole 并将该 ClusterRole 绑定到 RoleBinding 所在的姓名空间。 假如你期望将某 ClusterRole 绑定到集群中一切姓名空间,你要运用 ClusterRoleBinding。

下面的指令是在Kubernetes集群中创立一个名为developer-binding-tantianran的人物绑定目标,其效果是将一个用户(tantianran)与一个名为developer的人物相关起来。

kubectlcreaterolebindingdeveloper-binding-tantianran--role=developer--user=tantianran--namespace=rook-ceph
  • –role选项指定了要绑定的人物,这里是developer。
  • –user选项指定了要绑定到该人物的用户,这里是tantianran。

这意味着,一旦人物绑定目标被创立,用户tantianran就将取得developer人物的权限。

对应的yaml如下:

apiVersion:rbac.authorization.k8s.io/v1
kind:RoleBinding
metadata:
name:developer-binding-tantianran
namespace:rook-ceph
roleRef:
apiGroup:rbac.authorization.k8s.io
kind:Role
name:developer
subjects:
-apiGroup:rbac.authorization.k8s.io
kind:User
name:tantianran

列出rook-ceph命名空间下的RoleBinding:

[root@k8s-a-masterapi-user]#kubectlgetrolebinding-nrook-ceph
NAMEROLEAGE
cephfs-csi-provisioner-role-cfgRole/cephfs-external-provisioner-cfg15d
developer-binding-tantianranRole/developer14s#这个是方才创立的
rbd-csi-nodeplugin-role-cfgRole/rbd-csi-nodeplugin15d
rbd-csi-provisioner-role-cfgRole/rbd-external-provisioner-cfg15d
rook-ceph-cluster-mgmtClusterRole/rook-ceph-cluster-mgmt15d
rook-ceph-cmd-reporterRole/rook-ceph-cmd-reporter15d
rook-ceph-mgrRole/rook-ceph-mgr15d
rook-ceph-mgr-systemClusterRole/rook-ceph-mgr-system15d
rook-ceph-osdRole/rook-ceph-osd15d
rook-ceph-purge-osdRole/rook-ceph-purge-osd15d
rook-ceph-rgwRole/rook-ceph-rgw15d
rook-ceph-systemRole/rook-ceph-system15d

7. 增加到kubeconfig

kubeconfig 是 Kubernetes 集群客户端的配置文件,它包含衔接到 Kubernetes API Server 所需的信息,包含 API Server 地址、证书、认证方法等。

最终一步是将这个用户增加到 kubeconfig文件。首要,需求增加新的凭证:

kubectlconfigset-credentialstantianran--client-key=tantianran.key--client-certificate=tantianran.crt--embed-certs=true--namespace=rook-ceph
  • tantianran 是用户凭证条目的称号,能够自界说。
  • –client-key=tantianran.key 表明运用名为 tantianran.key 的客户端密钥文件作为用户凭证的一部分。客户端密钥用于对 API 服务器进行身份验证。
  • –client-certificate=tantianran.crt 表明运用名为 tantianran.crt 的客户端证书文件作为用户凭证的一部分。客户端证书用于对 API 服务器进行身份验证。
  • –embed-certs=true 表明将客户端证书嵌入到 kubeconfig 文件中,而不是将其作为文件引证。这能够协助简化 kubeconfig 文件的管理。
  • –namespace=rook-ceph 表明在 rook-ceph 命名空间中运用该用户凭证。命名空间用于将 Kubernetes 资源划分为不同的逻辑组。

运用 kubectl config set-credentials 指令创立了名为 tantianran 的用户凭证,那么能够在输出结果中搜索 tantianran 来检查该用户凭证的详细信息。下面是运用 kubectl config view 指令检查 kubeconfig 文件中用户凭证的示例输出:

[root@k8s-a-masterapi-user]#kubectlconfigview
apiVersion:v1
clusters:
-cluster:
certificate-authority-data:DATA+OMITTED
server:https://192.168.11.10:6443
name:kubernetes
contexts:
-context:
cluster:kubernetes
user:kubernetes-admin
name:kubernetes-admin@kubernetes
-context:
cluster:kubernetes
user:tantianran
name:tantianran
current-context:kubernetes-admin@kubernetes
kind:Config
preferences:{}
users:
-name:kubernetes-admin
user:
client-certificate-data:REDACTED
client-key-data:REDACTED
-name:tantianran
user:
client-certificate-data:REDACTED
client-key-data:REDACTED

在上述输出中,能够看到名为 tantianran 的用户凭证信息,包含客户端证书、客户端密钥和命名空间等。

然后,增加上下文:

kubectlconfigset-contexttantianran--cluster=kubernetes--user=tantianran--namespace=rook-ceph

kubectl config set-context 指令用于创立或修正 kubeconfig 文件中的上下文。上下文包含了与一个 Kubernetes 集群的衔接所需的一切信息,包含集群、用户和命名空间等。上面的参数阐明如下:

  • tantianran 是上下文的称号
  • –cluster 参数指定了集群称号为 kubernetes
  • –user 参数指定了用户称号为 tantianran
  • –namespace 参数指定了默许命名空间为 rook-ceph。 简而言之,这个指令创立了一个名为 tantianran 的上下文,该上下文与 kubernetes 集群建立衔接,并运用 tantianran 用户进行身份验证。一起,该上下文默许的命名空间为 rook-ceph,经过实战,其实是没必要指定命名空间。因为,就算指定了命名空间,当不管是检查仍是删去上下文的时分,不管有没有指定命名空间都是能够的。比方检查的时分,不指定命名空间也能查到,比方删去的时分,不指定命名空间照样也能删去。

假如要删去上下文能够用下面的指令:

kubectlconfigdelete-contexttantianran
#或
kubectlconfigdelete-contexttantianran-nrook-ceph

增加后,检查当时可用的 Kubernetes 配置文件上下文:

[root@k8s-a-masterapi-user]#kubectlconfigget-contexts
CURRENTNAMECLUSTERAUTHINFONAMESPACE
*kubernetes-admin@kuberneteskuberneteskubernetes-admin
tantianrankubernetestantianranrook-ceph
#或
[root@k8s-a-masterapi-user]#kubectlconfigget-contexts-nrook-ceph
CURRENTNAMECLUSTERAUTHINFONAMESPACE
*kubernetes-admin@kuberneteskuberneteskubernetes-admin
tantianrankubernetestantianranrook-ceph
[root@k8s-a-masterapi-user]#

上下文切换:

#切换到一般用户的上下文
[root@k8s-a-masterapi-user]#kubectlconfiguse-contexttantianran
#列出当时上下文
[root@k8s-a-masterapi-user]#kubectlconfigget-contexts
CURRENTNAMECLUSTERAUTHINFONAMESPACE
kubernetes-admin@kuberneteskuberneteskubernetes-admin
*tantianrankubernetestantianran#此处的*号代表当时上下文是处于这个账户下
#把上下文切换回admin:
kubectlconfiguse-contextkubernetes-admin@kubernetes

检查当时用户是否能够履行给定操作(不管运用何种鉴权形式该指令都能够工作,我这里是RBAC(依据人物的拜访操控)的鉴权形式):

#在admin上下文中履行检查操作:
[root@k8s-a-masterapi-user]#kubectlauthcan-ilistpods--namespacerook-ceph--astantianran
yes
[root@k8s-a-masterapi-user]#kubectlauthcan-ilistpods--namespacedefault--astantianran#能够看到,处于default命名空间下的pod的,tantianran是没有权限的
no
#假如现已切换到了一般账户的上下文中,那么能够用下面的指令检查:
[root@k8s-a-masterapi-user]#kubectlconfiguse-contexttantianran
[root@k8s-a-masterapi-user]#kubectlauthcan-icreatepods--namespacerook-ceph
yes
[root@k8s-a-masterapi-user]#kubectlauthcan-icreatepods--namespacedefault
no

客户端库

当要运用 Kubernetes REST API 来操作K8S各种资源时,能够依据自己喜爱的编程言语来选择适宜的客户端库。客户端库有官方支撑的,也有社区维护的。官方支撑的 Kubernetes 客户端库有Go、Python、C、Java等等,作为运维开发工程师,能够运用Go或许Python。而我,以前是写Python的,老早就现已完全转Go了,并且仍是Go的深度发烧友。关于客户端库更多的信息可参阅:kubernetes.io/zh-cn/docs/…

我计划别离运用Golang和Python的K8S客户端库来进行编码,今天的时间有限,放到下篇共享。

本文转载于WX公众号:不背锅运维(喜爱的盆友重视咱们):mp.weixin.qq.com/s/G8jK0IBcf…