2025年kubelete服务不断重启(kubectl 停止服务)

kubelete服务不断重启(kubectl 停止服务)本文章基于 k8s release 1 17 分支代码 代码位于 plugin pkg admission serviceaccou 目录 代码 admission go 1 api server 作为常用的服务端应用 包含认证模块 Authenticati 授权模块 Authorizatio 和准入模块 Admission Plugin 可以理解为请求中间件模块

大家好,我是讯享网,很高兴认识大家。



kubernetes设置控制节点不调度_官网
讯享网

本文章基于 k8s release-1.17 分支代码,代码位于 plugin/pkg/admission/serviceaccount 目录,代码:admission.go[1] 。

api-server 作为常用的服务端应用,包含认证模块 Authentication、授权模块 Authorization 和准入模块 Admission Plugin(可以理解为请求中间件模块 middleware pipeline),以及存储依赖 Etcd。其中,针对准入插件,在 api-server 进程启动时,启动参数 –enable-admission-plugins 需要包含 ServiceAccount 准入控制器来开启该中间件,可以见官方文档:enable-admission-plugins[2] 。ServiceAccount Admission Plugin 主要作用包含:

  • 如果提交的 pod yaml 里没有指定 spec.serviceAccountName 字段值,该插件会添加默认的 default ServiceAccount;
  • 判断 spec.serviceAccountName 指定的 service account 是否存在,不存在就拒绝请求;
  • 为该 pod 创建个 volume,且该 volume source 是 SecretVolumeSource,该 secret 来自于 service account 对象引用的 secret;
  • 如果提交的 pod yaml 里没有指定 spec.ImagePullSecrets 字段值,那就将 service account 对象引用的 ImagePullSecrets 字段值来补位,并且该 volume 会被 mount 到 pod 的 /var/run/secrets/kubernetes.io/serviceaccount 目录中;

比如,往 api-server 进程提交个 pod 对象:

就会看到该 pod 对象被 ServiceAccount Admission Plugin 处理后,spec.serviceAccountName 指定了 default ServiceAccount;增加了个 SecretVolumeSource 的 Volume,volume name 为 ServiceAccount 的 secrets 的 name 值,mount 到 pod 的 /var/run/secrets/kubernetes.io/serviceaccount目录中;以及因为 pod 和 default service account 都没有指定 ImagePullSecrets 值,pod 的 spec.ImagePullSecrets 没有值:

kubernetes设置控制节点不调度_github_02

serviceaccount_admission_plugin

并且,volume 指定的 secret name 是 default service account 的 secrets 的 name 值:

kubernetes设置控制节点不调度_中间件_03

serviceaccount_default

那么,有个问题,ServiceAccount Admission Controller 或者说 ServiceAccount 中间件,是如何做到的呢?

就和我们经常见到的一些服务端框架做的 middleware 中间件模块一样,api-server 框架也是用插件化形式来定义一个个准入控制器 Admission Controller,并且会调用该插件的Admit()方法, 来判断当前请求是否通过该准入控制器。

AdmissionController 准入控制器实例化

实例化操作很简单,需要注意的是:MountServiceAccountToken 为 true,表示默认去执行 mount volume 操作,且 mount 到 pod 的默认目录;并且资源操作是 Create 操作时才去执行当前准入控制器。代码见 L103-L121[3]:

Admit 操作

Admit 操作是该中间件的核心逻辑,主要工作上文已经详细描述,这里从代码角度学习下,代码见:L160-L248[4] 。

ServiceAccount 检查

首先是检查 pod yaml 中有没有指定 ServiceAccount,没有指定就设置默认的default ServiceAccount 对象,并且同时检查该 ServiceAccount 在当前 namespace 内是否真的存在:

ServiceAccount 检查逻辑很简单,主要目的是为 pod 填补 ServiceAccount 值,因为服务账号就是给 pod 调用 api-server 进程用的,关于服务账号 ServiceAccount 作用可见官网:用户账号与服务账号[5]

Mount Volume

Mount Volume 核心就是会创建个 volume,并 mount 到 pod 每个容器内指定目录,该目录下包含 ca.crt、namespace和token文件 ,供 pod 调用 api-server 时使用。从源码角度看看如何创建 volume 以及如何 mount 的 L426-L567[6] :

Mount Volume 逻辑也很简单,主要就是为 pod 创建个 volume,并且 mount 到每一个容器的指定路径。该 volume 内包含的数据来自于 ServiceAccount 引用的 secrets 的数据,即 ca.crt、namespace和token 数据文件,这些数据是调用 api-server 时需要的认证数据,且 token 数据已经经过私钥文件签名过了。

那么有个问题,创建 ServiceAccount 时对应的这些 secret 对象是怎么来的呢?secret 里的 token 文件既然已经被私钥签名过,那 api-server 必然需要对应的公钥文件来验证签名才对?至于 secret 对象是怎么来的问题,这是 kube-controller-manager 里的 ServiceAccount 模块的 TokenController 创建的,创建时会用私钥进行签名,所以 kube-controller-manager 启动时必须带上私钥参数 –service-account-private-key-file ,具体可见官网 service-account-private-key-file[7] ;至于 api-server 必须使用对应的公钥来验证签名,同理,kube-apiserver 启动时,也必须带上公钥参数 –service-account-key-file ,具体可见官网 service-account-key-file[8]

本文分析了 ServiceAccount Admission Controller 中间件的主要业务逻辑,如何为 pod 对象补充 serviceAccount、imagePullSecrets 字段数据, 以及创建并挂载 service account volume,供 pod 调用 api-server 使用。总体逻辑比较简单,源码值得学习,供自己二次开发 k8s 时参考学习。

serviceaccounts-controller 源码官网解析[9]

为 Pod 配置服务账户[10]

服务账号令牌 Secret[11]

admission.go[12]

Kubernetes Proposal - Admission Control[13]

参考资料

[1]

admission.go: https://github.com/kubernetes/kubernetes/blob/release-1.17/plugin/pkg/admission/serviceaccount/admission.go

[2]

enable-admission-plugins: https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/

[3]

L103-L121: https://github.com/kubernetes/kubernetes/blob/release-1.17/plugin/pkg/admission/serviceaccount/admission.go#L103-L121

[4]

L160-L248: https://github.com/kubernetes/kubernetes/blob/release-1.17/plugin/pkg/admission/serviceaccount/admission.go#L160-L248

[5]

用户账号与服务账号: https://kubernetes.io/zh/docs/reference/access-authn-authz/service-accounts-admin/#user-accounts-versus-service-accounts

[6]

L426-L567: https://github.com/kubernetes/kubernetes/blob/release-1.17/plugin/pkg/admission/serviceaccount/admission.go#L426-L567

[7]

service-account-private-key-file: https://kubernetes.io/docs/reference/command-line-tools-reference/kube-controller-manager/

[8]

service-account-key-file: https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/

[9]

serviceaccounts-controller 源码官网解析: https://kubernetes.io/zh/docs/reference/access-authn-authz/service-accounts-admin/

[10]

为 Pod 配置服务账户: https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-service-account/

[11]

服务账号令牌 Secret: https://kubernetes.io/zh/docs/concepts/configuration/secret/#service-account-token-secrets

[12]

admission.go: https://github.com/kubernetes/kubernetes/blob/v1.17.0/plugin/pkg/admission/serviceaccount/admission.go

[13]

Kubernetes Proposal - Admission Control: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/admission_control.md

小讯
上一篇 2025-05-18 09:24
下一篇 2025-05-03 16:44

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/150312.html