创建 tls 客户端 凭据时发生严重错误。内部错误状态为 10013_深度解读:输入 kubectl run 后,到底发生了什么?...

本文详细探讨了使用`kubectl run`命令部署应用时,从客户端到Kubelet请求的生命周期。首先,Kubectl进行验证和生成HTTP请求,与kube-apiserver进行认证和授权,然后通过Admission Controller检查。接着,Deployment Controller和ReplicaSet Controller创建和管理资源,Scheduler将Pod调度到节点。最后,Kubelet负责Pod的同步和容器的启动,包括网络配置和CRI接口的使用。
摘要由CSDN通过智能技术生成

8beb633b02e235c8e708dc927c118777.png
作者:Jamie Hannaford
翻译:bbbmj(才云)
校对:bot(才云)
源代码解释版( 强烈建议阅读): https://github.com/bbbmj/what-happens-when-k8s

想象一下,当你想在 Kubernetes 集群部署 Nginx 时,你会执行以下命令:

983d061d464ce224b0bda7fdea6a938c.png

几秒后,你将看到三个 Nginx Pod 分布在集群 Worker 节点上。这相当神奇,但它背后究竟发生了什么?Kubernetes 最为人称道的地方是,它通过用户友好的 API 处理跨基础架构的工作负载部署,通过简单的抽象隐藏其背后的复杂性。但是,为了充分理解它为我们提供的价值,我们需要理解它的原理。本文将带领你充分了解从客户端到 Kubelet 请求的完整生命周期,并在必要时通过源代码解释它到底是什么。

Kubectl

验证和生成器

首先,当我们按下回车执行命令后,Kubectl 会执行客户端验证,以确保非法请求(如创建不支持的资源或使用格式错误的镜像名称)快速失败,并不会发送给 kube-apiserver——即通过减少不必要的负载来提高系统性能

验证通过后, Kubectl 开始封装它将发送给 kube-apiserver 的 HTTP 请求。在 Kubernetes 中,访问或更改状态的所有尝试都通过 kube-apiserver 进行,后者又与 etcd 进行通信。Kubectl 客户端也不例外。为了构造 HTTP 请求, Kubectl 使用生成器(generators),这是一种负责序列化的抽象

你可能没有注意到,通过执行 kubectl run,除了运行 Deployment,我们还能利用指定参数 --generator 来部署其他工作负载。

如果没有指定 --generator 参数的值, Kubectl 会自动推断资源的类型,具体如下:

  • 具有 --restart-policy=Always 的资源被视为 Deployment;
  • 具有 --restart-policy=OnFailure 的资源被视为 Job;
  • 具有 --restart-policy=Never 的资源被视为 Pod。

Kubectl 还将确定是否需要触发其他操作,例如记录命令(用于部署或审计),或者此命令是否是 dry run。

当 Kubectl 判断出要创建一个 Deployment 后,它将使用 DeploymentV1Beta1 generator 配合我们提供的参数,生成一个运行时对象(Runtime Object)。

API Group 和版本协商

这里值得指出的是, Kubernetes 使用的是一个分类为 API Group 的版本化 API。它旨在对资源进行分类,以便于推理。

同时,它还为单个 API 提供了更好的版本化方案。例如,Deployment 的 API Group 为 apps,其最新版本为 v1。这也是我们为什么需要在 Deployment manifests 顶部指定 apiVersion: apps/v1 的原因。

回归正文, Kubectl 生成运行时对象之后,就开始为它查找合适的 API Group 和版本,然后组装一个知道该资源各种 REST 语义的版本化客户端。

这个发现阶段被称为版本协商(version negotiation),这时 Kubectl 会扫描 remote API 上的 /apis 路径以检索所有可能的 API Group。

由于 kube-apiserver 在 /apis 路径中公开其 OpenAPI 格式的 scheme 文档,客户端可以借此轻松找到匹配的 API。

为了提高性能, Kubectl 还将 OpenAPI scheme 缓存到 ~/.kube/cache/discovery 目录。如果要了解 API 发现的完整过程,你可以试着删除该目录并在运行 Kubectl 命令时将 -v 参数的值设为最大,然后你就可以在日志中看到所有试图找到这些 API 版本的 HTTP 请求。最后一步才是真正地发送 HTTP 请求。一旦请求获得成功的响应, Kubectl 将会根据所需的输出格式打印 success message。

客户端验证

我们在上文中没有提到的一件事是客户端身份验证(这是在发送 HTTP 请求之前处理的),现在让我们来看看。

为了成功发送请求, Kubectl 需要先进行身份验证。用户凭据一般存储在 kubeconfig 文件中,但该文件可以存储在其他不同位置。为了定位到它,我们可以执行以下操作:

  • 如果指定参数 --kubeconfig,那么采用该值;
  • 如果指定环境变量 $KUBECONFIG,那么采用该值;
  • 否则查看默认的目录,如 ~/.kube,并使用找到的第一个文件。

解析文件后,它会确定当前要使用的上下文、当前指向的集群以及当前与用户关联的所有身份验证信息。如果用户提供了额外的参数(例如 --username),则这些值优先,并将覆盖 kubeconfig 中指定的值。

一旦有了上述信息, Kubectl 就会填充客户端的配置,以便它能够适当地修饰 HTTP 请求:

  • x509 证书使用 tls.TLSConfig 发送(包括 CA 证书);
  • bearer tokens 在 HTTP 请求头 Authorization 中发送;
  • 用户名和密码通过 HTTP 基础认证发送;
  • OpenID 认证过程是由用户事先手动处理的,产生一个像 bearer token 一样被发送的 token。

9bc29ef4cfadb3e424cf9ede2876591b.png

kube-apiserver

认证

我们的请求已经发送成功,接下来呢?kube-apiserver!

kube-apiserver 是客户端和系统组件用来持久化和检索集群状态的主要接口。为了执行其功能,它需要能够验证请求是否合法,这个过程被称为认证 (

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值