kubernetes 理论知识点汇总
环境信息
- Kubernetes 1.29
kubeadm 初始化集群
Network setup
组件的 advertise IP 地址选择
Kubernetes 中的组件(如 Kubeadm
、Kube-apiserver
等)在初始化启动时,都需要在节点(主机)上找到一个合适的 IP 作为组件的 advertising
/listening
的地址。[1]
默认情况下,此 IP 是主机上默认路由对应的网卡所在的 IP。
ip route show |
如果系统上有多个默认路由,组件会尝试使用第一个默认路由对应的网卡所在的 IP。如果系统上没有默认路由,并且未明确为组件配置 IP,组件会初始化失败并退出
组件选择的 IP 地址将会作为 X.509 证书的 SAN(Subject Alternative Name) 的一部分。因此在系统初始化运行之后修改 IP 需要重新签发证书并重启相关组件。
Pod 网段选择
Pod 的网段必须不能和主机网络重叠,如果选用的网络插件的网络和主机的网段重叠,必须为网络插件选择合适的和主机不同的网段,在集群初始化时通过参数 --pod-network-cidr
配置,并在安装网络插件时在其 YAML 文件中修改为对应的网段。 [4]
control-plane-endpoint 参数说明
--control-plane-endpoint
选项用来配置 api-server
的共享地址,可以是域名或者负载均衡器的 IP。 [2]
如果是单主节点的 Kubernetes 集群,想要扩展成为多个 Master 节点(高可用),初始化时没有 --control-plane-endpoint
,是不被支持的。
因此为了后期可以由单个 Master 节点扩展为多个 Master 节点,即高可用,初始化节点时,建议加上此选项配置 api-server
的负载均衡地址。
<– more –>
admin.conf 的重要性
kubeadm init
初始化集群成功后,会产生一个 kubeconfig
文件 /etc/kubernetes/admin.conf
,此配置中包含了一个绑定到 cluster-admin
的 ClusterRole 的组,其拥有对整个集群的控制权,不要将其共享给任何人。[3]
kubeadm init
初始化集群成功后,同时会生成一个名为 super-admin.conf
的 kubeconfig
文件,其中配置的超级用户可以跳过 authorization layer
,比如 RBAC。不要将其共享给任何人。建议将其保存在一个安全的位置。
Node
节点名称
在 Kubernetes 集群中,节点名称(Node Name)唯一的标识一个节点。在一个集群中,不能有多个名称一样的节点,Kubernetes 系统默认同一个 节点名(Node Name) 的实例将具有同样的一个状态和属性 [7]
配置节点为不可调度
将节点标记为 不可调度(unschedulable ) 会阻止系统调度新的 Pod 到节点上,但是不会影响节点上已有的 Pod。
Labels Selectors Annotations
Label 主要用来给 Kubernetes 中的对象添加 可识别属性。 Label 可以提供高效的查询和匹配以选择 Kubernetes 中的对象,Lables 可以在对象创建时或者运行过程中随时做变更。
不具有识别属性的信息 不建议用作 Labels,而是应该写入 Annotations 中。[5]
Label Key 由 2 部分构成:
- (可选的)前缀。系统组件(如
kube-scheduler
,kube-controller-manager
,kube-apiserver
,kubectl
) 或者第三方自动化组件为对象添加 labels 时必须带有前缀(prefix)。kubernetes.io/
andk8s.io/
是为 Kubernetes 核心系统保留的前缀 - (必须的)名字。
Annotations 的 Key 命名规则和 Label Key 基本一致 [6]
集群间通讯流量说明
API Server 到 kubelet
API Server 请求 kubelet
的主要目的包括: [8]
- 获取到 Pods 的日志
- (比如使用
kubectl
) Attach 到 Pods 中的容器 - 提供
kubelet
的端口转发功能。
默认情况下,API 服务器不检查
kubelet
的服务证书。这使得此类连接容易受到中间人攻击, 在非受信网络或公开网络上运行也是 不安全的。
为了对这个连接进行认证,使用--kubelet-certificate-authority
标志给 API 服务器提供一个根证书包,用于kubelet
的服务证书。
API Server 到 nodes, pods 和 services
从 API 服务器到节点、Pod 或服务的连接默认为纯 HTTP 方式,因此既没有认证,也没有加密。 这些连接可通过给 API URL 中的节点、Pod 或服务名称添加前缀 https: 来运行在安全的 HTTPS 连接上。 不过这些连接既不会验证 HTTPS 末端提供的证书,也不会提供客户端证书。 因此,虽然连接是加密的,仍无法提供任何完整性保证。 这些连接 目前还不能安全地 在非受信网络或公共网络上运行。 [8]
Kubernetes 支持使用 SSH tunnels 来加密从 API 到 nodes 的链接(目前已经处于废弃状态,推荐使用 Konnectivity service 替代)。
Leases
Kubernetes 使用 Lease API 来更新 kubelet
发送到 Kubernetes API Server 的心跳信息。Kubernetes 中的每一个节点在 kube-node-lease
Namespace 中都有一个 Lease
Object。kubelet
向系统上报心跳的过程,就是在更新对应的 Lease
Object 的 spec.renewTime
字段,Kubernetes 控制平面会使用这个上报的时间戳来决定节点是否可用 [9]
kubectl describe lease -n kube-node-lease k8s-admin |
Leases 也被用来确保 HA 的组件(类似 kube-controller-manager
和 kube-scheduler
)在同一时刻只有一个实例提供服务,其他实例处于备用状态 [9]
kubelet
串行和并行拉取镜像
Kubelet 默认(同一个节点)串行的拉取镜像,即同一时间只发送一个拉取镜像的请求到 Registry Server,其他的拉取镜像的请求保持等待,直到当前请求处理完成。多个节点上的镜像拉取请求是隔离的,即不同的节点在同一时间是并行的拉取镜像的。 [10]
如果要配置一个节点上的 Kubelet 并行的拉取镜像,可以在 kubelet 的配置中配置 serializeImagePulls
为 false
,前提是 Registry Server 和 CRI 支持并行拉取镜像。
Pod
Pod 状态
Pod 的状态字段(status
) 是一个 PodStatus Object。其中包含 phase
字段。phase
字段描述/记录了 Pod 在其整个生命周期中所处的阶段 [11]
phase
字段可以有以下值:
Value | Description |
---|---|
Pending |
Kubernetes 集群已经接收到创建 Pod 的请求,并且开始调度到节点、下载容器镜像并启动容器,但是有一个或多个容器还未正常运行 |
Running |
Pod 已经被调度到某个节点,并且 Pod 中所有的容器已经被创建,至少其中的一个容器已经处于运行状态或重启中 |
Succeeded |
Pod 中所有的容器都已经成功终止,并且不会再被重启 |
Failed |
Pod 中所有的容器都被终止,但至少有一个容器终止失败,也就是说,容器要么以非零状态码退出或者是被系统终止 |
Unknow |
因为某些原因,Pod 的状态获取不到。这个经常发生在和 Pod 运行的节点通信异常时 |
Pod 中的容器的状态
Kubernetes 会跟踪 Pod 中每个容器的状态。一旦通过 Scheduler 将 Pod 分配到某个 Node,Kubernetes 会通过 CRI 创建 Pod 中的容器。
在 Kubernetes 中,容器可以有以下 3 种状态 [11]
Value | Description |
---|---|
Waiting |
表示容器正在进行必要的操作以正常启动,比如拉取镜像、应用 Secret 数据等。当容器处于此状态时,可以通过 kubectl describe pod 查看输出中对应容器的信息,一般会包含一个 Reason 字段简述 Waiting 的原因 |
Running |
表示容器在正常运行 |
Terminated |
表示容器运行结束或者因为某些原因失败。详细信息可以通过 kubectl describe pod 查看 |
QoS
Kubernetes 会根据 Pod 定义中的 resource requests and limits
将 Pod 划归到某一个 QoS 类中,Kubernetes 将会根据 QoS 类来决定在节点资源不足的情况下,哪些 Pod 将会被优先驱逐(Evict)。目前存在的 QoS 类主要有以下三个 [12]
QoS Class | 说明 | 被驱逐权重 |
---|---|---|
Guaranteed |
Pod 中的 每个容器必须定义 CPU & Mem request 和 limit ,并且 request 的值等于 limit 的值,确保系统会预留定义的资源给 Pod 和其中的容器 |
最后被驱逐 |
Burstable |
Pod 中 至少有一个容器定义了 CPU 或 Mem 的 request 。可以不定义 limit , 如果未定义 limit ,默认可以使用节点上所有可用的资源。 |
中间级别 |
BestEffort |
未定义任何 CPU 或 Mem 的 request 或 limit |
最先被驱逐 |
Memory QoS 基于系统内核的 cgroup v2 实现 [12]
Pod 中如果有个容器因为 Limit 被 kill,系统只会 kill 掉这一个容器并重启之,不会影响其他容器
脚注
- 1.Network setup ↩
- 2.Initializing your control-plane node ↩
- 3.admin.conf ↩
- 4.Installing a Pod network add-on ↩
- 5.Labels and Selectors ↩
- 6.Annotations Key Syntax and character set ↩
- 7.Node name uniqueness ↩
- 8.API server to kubelet ↩
- 9.Node heartbeats ↩
- 10.Serial and parallel image pulls ↩
- 11.Pod phase ↩
- 12.Quality of Service ↩