Convert site to Hugo (#8316)
This commit converts content and layout to use Hugo.
This commit is contained in:
committed by
k8s-ci-robot
parent
7745f0e0c5
commit
7f3b633aa0
@@ -0,0 +1,248 @@
|
||||
title: 云控制器管理器的基本概念
|
||||
|
||||
## 云控制器管理器
|
||||
|
||||
云控制器管理器(CCM)这个概念创建的初衷是为了让特定的云服务供应商代码和Kubernetes核心相互独立演化。云控制器管理器与其他主要组件如Kubernetes控制器管理器,API服务器和调度程序同时运行。云控制器管理器也可以作为Kubernetes的插件启动,这种情况下,CCM运行在Kubernetes系统之上。
|
||||
|
||||
云控制器管理器基于插件机制设计,允许新的云服务供应商通过插件轻松地与Kubernetes集成。目前已经有在Kubernetes上加入新的云服务供应商计划,并为云服务供应商提供从原先的旧模式迁移到新CCM模式的方案。
|
||||
|
||||
本文讨论了云控制器管理器背后的概念,并提供了相关功能的详细信息。
|
||||
|
||||
下面这张图描述了没有云控制器管理器的Kubernetes集群架构:
|
||||
|
||||

|
||||
|
||||
## 设计
|
||||
|
||||
在上图中,Kubernetes和云服务供应商通过几个不同的组件进行了集成,分别是:
|
||||
|
||||
* Kubelet
|
||||
* Kubernetes 控制管理器
|
||||
* Kubernetes API服务器
|
||||
|
||||
而CCM整合了前三个组件中的所有依赖于云的逻辑,用来创建与云的单点集成。新架构如下图所示:
|
||||
|
||||

|
||||
|
||||
## CCM的组件
|
||||
|
||||
CCM突破了Kubernetes控制器管理器(KCM)的一些功能,并将其作为一个独立的进程运行。具体而言,它打破了KCM中与云相关的控制器。KCM具有以下依赖于云的控制器引擎:
|
||||
|
||||
* 节点控制器
|
||||
* 卷控制器
|
||||
* 路由控制器
|
||||
* 服务控制器
|
||||
|
||||
在1.8版本中,当前运行中的CCM从上面的列表中运行以下控制器:
|
||||
|
||||
* 节点控制器
|
||||
* 路由控制器
|
||||
* 服务控制器
|
||||
|
||||
另外,它运行另一个名为 PersistentVolumeLabels Controller 的控制器。这个控制器负责对在GCP和AWS云里创建的PersistentVolumes的域(Zone)和区(Region)标签进行设置。
|
||||
|
||||
**注意**:卷控制器被特意设计为CCM之外的一部分。由于其中涉及到的复杂性和对现有供应商特定卷的逻辑抽象,因此决定了卷控制器不会被移动到CCM之中。
|
||||
|
||||
原本计划使用CCM来支持卷的目的是为了引入FlexVolume卷来支持可插拔卷。然而,官方正在计划使用更具备竞争力的CSI来取代FlexVolume卷。
|
||||
|
||||
考虑到这些正在进行中的变化,我们决定暂时停止当前工作直至CSI准备就绪。
|
||||
|
||||
云服务供应商工作组(wg-cloud-provider)正在开展相关工作,以实现通过CCM支持PersistentVolume的功能。详细信息请参见[kubernetes/kubernetes#52371](https://github.com/kubernetes/kubernetes/pull/52371)。
|
||||
|
||||
## CCM功能
|
||||
|
||||
CCM从Kubernetes组件中继承了与云服务供应商相关的功能。本节基于被CCM继承其功能的组件展开描述。
|
||||
|
||||
### 1. Kubernetes 控制器管理器
|
||||
|
||||
CCM的大部分功能都来自KCM。 如上一节所述,CCM运行以下控制引擎:
|
||||
|
||||
* 节点控制器
|
||||
* 路由控制器
|
||||
* 服务控制器
|
||||
* PersistentVolumeLabels控制器
|
||||
|
||||
#### 节点控制器
|
||||
|
||||
节点控制器负责通过从云服务供应商获得有关在集群中运行的节点的信息来初始化节点。节点控制器执行以下功能:
|
||||
|
||||
1.使用云特定域(Zone)/区(Region)标签初始化节点。
|
||||
|
||||
1.使用特定于云的实例详细信息初始化节点,例如类型和大小。
|
||||
|
||||
1.获取节点的网络地址和主机名。
|
||||
|
||||
1.如果节点无响应,检查该节点是否已从云中删除。如果该节点已从云中删除,则删除Kubernetes节点对象。
|
||||
|
||||
#### 路由控制器
|
||||
|
||||
路由控制器负责为云配置正确的路由,以便Kubernetes集群中不同节点上的容器可以相互通信。路由控制器仅适用于Google Compute Engine平台。
|
||||
|
||||
#### 服务控制器
|
||||
|
||||
服务控制器负责监听服务的创建、更新和删除事件。根据Kubernetes中各个服务的当前状态,它将配置云负载平衡器(如ELB或Google LB)以反映Kubernetes中的服务状态。此外,它还确保云负载均衡器的服务后端保持最新。
|
||||
|
||||
#### PersistentVolumeLabels 控制器
|
||||
|
||||
PersistentVolumeLabels控制器在AWS的EBS卷、GCE的PD卷创建时申请标签,这使得用户不再需要手动设置这些卷标签。
|
||||
|
||||
这些标签对于pod的调度工作是非常重要的,因为这些卷只能在它们所在的域(Zone)/区(Region)内工作,因此所有使用这些卷的pod都必须要在同一个域/区中才能保证进行调度正常进行。
|
||||
|
||||
PersistentVolumeLabels控制器是专门为CCM创建的; 也就是说,在CCM创建之前它是不存在的。这样做是为了将Kubernetes API服务器(它是一个许可控制器)中的PV标签逻辑移动到CCM。 它不在KCM上运行。
|
||||
|
||||
### 2. Kubelet
|
||||
|
||||
Node控制器包含kubelet中依赖于云的功能。在系统引入CCM组件之前,是由kubelet采用包含云特定信息的方式对节点进行初始化,如IP地址、区(Region)/域(Zone)标签和实例类型信息;引入CCM之后,这部分的初始化操作就从kubelet转移到了CCM中。
|
||||
|
||||
在引入CCM后的新的模型中,kubelet采用不包含云特定信息的方式初始化一个节点。但是,它会为新创建的节点添加一个污点,使得该节点不可被立即调度,直到CCM使用包含云的特定信息初始化节点后,才会删除该污点,使得该节点可被调度。
|
||||
|
||||
### 3. Kubernetes API服务器
|
||||
|
||||
PersistentVolumeLabels控制器将Kubernetes API服务器的依赖于云的功能移至CCM,如前面部分所述。
|
||||
|
||||
## 插件机制
|
||||
|
||||
云控制器管理器使用Go接口与外部对接从而实现功能扩展。具体来说,它使用了[这里](https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/cloud.go)定义的CloudProvider接口。
|
||||
|
||||
上面强调的四个共享控制器的实现,以及一些辅助设施(scaffolding)和共享的云服务供应商接口,将被保留在Kubernetes核心当中。但云服务供应商特有的实现将会建立在核心之外,并实现核心中定义的接口。
|
||||
|
||||
有关开发插件的更多信息,请参阅
|
||||
[开发云控制器管理器](/docs/tasks/administrators-cluster/developing-cloud-controller-manager/)。
|
||||
|
||||
## 授权
|
||||
|
||||
本节分解了CCM对各种API对象的访问,以执行其操作。
|
||||
|
||||
### 节点控制器
|
||||
|
||||
节点控制器仅适用于节点对象。它需要完全访问权限来获取、列出、创建、更新、修补、监视和删除节点对象。
|
||||
|
||||
v1/Node:
|
||||
- Get
|
||||
- List
|
||||
- Create
|
||||
- Update
|
||||
- Patch
|
||||
- Watch
|
||||
|
||||
### 路由控制器
|
||||
|
||||
路由控制器监听节点对象的创建并配置合适的路由。它需要对节点对象的访问权限。
|
||||
|
||||
v1/Node:
|
||||
- Get
|
||||
|
||||
### 服务控制器
|
||||
|
||||
服务控制器侦听服务对象创建、更新和删除事件,然后对这些服务的端点进行恰当的配置。
|
||||
|
||||
要访问服务,它需要罗列和监控权限。要更新服务,它需要修补和更新权限。
|
||||
|
||||
要为服务设置端点,需要访问创建、列表、获取、监视和更新。
|
||||
|
||||
v1/Service:
|
||||
- List
|
||||
- Get
|
||||
- Watch
|
||||
- Patch
|
||||
- Update
|
||||
|
||||
### PersistentVolumeLabels 控制器
|
||||
|
||||
PersistentVolumeLabels控制器监听PersistentVolume(PV)创建事件并更新它们。该控制器需要访问列表、查看、获取和更新PV的权限。
|
||||
|
||||
v1/PersistentVolume:
|
||||
- Get
|
||||
- List
|
||||
- Watch
|
||||
- Update
|
||||
|
||||
### 其它
|
||||
|
||||
CCM核心的实现需要创建事件的权限,为了确保安全操作,需要创建ServiceAccounts的权限。
|
||||
|
||||
v1/Event:
|
||||
- Create
|
||||
- Patch
|
||||
- Update
|
||||
|
||||
v1/ServiceAccount:
|
||||
- Create
|
||||
|
||||
针对CCM的RBAC ClusterRole如下所示:
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: cloud-controller-manager
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- nodes
|
||||
verbs:
|
||||
- '*'
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- nodes/status
|
||||
verbs:
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- services
|
||||
verbs:
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- serviceaccounts
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- endpoints
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- update
|
||||
```
|
||||
|
||||
## 供应商实施
|
||||
|
||||
以下云服务供应商为自己的云部署了CCM。
|
||||
|
||||
* [Digital Ocean]()
|
||||
* [Oracle]()
|
||||
* [Azure]()
|
||||
* [GCE]()
|
||||
* [AWS]()
|
||||
|
||||
## 群集管理
|
||||
|
||||
[这里](/docs/tasks/administer-cluster/running-cloud-controller/#cloud-controller-manager)提供了配置和运行CCM的完整说明。
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
approvers:
|
||||
- dchen1107
|
||||
- roberthbailey
|
||||
- liggitt
|
||||
|
||||
title: Master 节点通信
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
|
||||
## 概览
|
||||
|
||||
|
||||
本文对 Master 节点(确切说是 apiserver)和 Kubernetes 集群之间的通信路径进行了分类。目的是为了让用户能够自定义他们的安装,对网络配置进行加固,使得集群能够在不可信的网络上(或者在一个云服务商完全公共的 IP 上)运行。
|
||||
|
||||
|
||||
## Cluster -> Master
|
||||
|
||||
|
||||
所有从集群到 master 的通信路径都终止于 apiserver(其它 master 组件没有被设计为可暴露远程服务)。在一个典型的部署中,apiserver 被配置为在一个安全的 HTTPS 端口(443)上监听远程连接并启用一种或多种形式的客户端[身份认证](/docs/admin/authentication/)机制。一种或多种客户端[身份认证](/docs/admin/authentication/)机制应该被启用,特别是在允许使用 [匿名请求](/docs/admin/authentication/#anonymous-requests) 或 [service account tokens](/docs/admin/authentication/#service-account-tokens) 的时候。
|
||||
|
||||
|
||||
应该使用集群的公共根证书开通节点,如此它们就能够基于有效的客户端凭据安全的连接 apiserver。例如:在一个默认的 GCE 部署中,客户端凭据以客户端证书的形式提供给 kubelet。请查看 [kubelet TLS bootstrapping](/docs/admin/kubelet-tls-bootstrapping/) 获取如何自动提供 kubelet 客户端证书。
|
||||
|
||||
|
||||
想要连接到 apiserver 的 Pods 可以使用一个 service account 安全的进行连接。这种情况下,当 Pods 被实例化时 Kubernetes 将自动的把公共根证书和一个有效的不记名令牌注入到 pod 里。`kubernetes` service (所有 namespaces 中)都配置了一个虚拟 IP 地址,用于转发(通过 kube-proxy)请求到 apiserver 的 HTTPS endpoint。
|
||||
|
||||
|
||||
Master 组件通过非安全(没有加密或认证)端口和集群的 apiserver 通信。这个端口通常只在 master 节点的 localhost 接口暴露,这样,所有在相同机器上运行的 master 组件就能和集群的 apiserver 通信。一段时间以后,master 组件将变为使用带身份认证和权限验证的安全端口(查看[#13598](https://github.com/kubernetes/kubernetes/issues/13598))。
|
||||
|
||||
|
||||
这样的结果使得从集群(在节点上运行的 nodes 和 pods)到 master 的缺省连接操作模式默认被保护,能够在不可信或公网中运行。
|
||||
|
||||
|
||||
## Master -> Cluster
|
||||
|
||||
|
||||
从 master(apiserver)到集群有两种主要的通信路径。第一种是从 apiserver 到集群中每个节点上运行的 kubelet 进程。第二种是从 apiserver 通过它的代理功能到任何 node、pod 或者 service。
|
||||
|
||||
|
||||
### apiserver -> kubelet
|
||||
|
||||
|
||||
从 apiserver 到 kubelet 的连接用于获取 pods 日志、连接(通过 kubectl)运行中的 pods,以及使用 kubele 的端口转发功能。这些连接终止于 kubelet 的 HTTPS endpoint。
|
||||
|
||||
|
||||
默认的,apiserver 不会验证 kubelet 的服务证书,这会导致连接遭到中间人攻击,因而在不可信或公共网络上是不安全的。
|
||||
|
||||
|
||||
为了对这个连接进行认证,请使用 `--kubelet-certificate-authority` 标记给 apiserver 提供一个根证书捆绑,用于 kubelet 的服务证书。
|
||||
|
||||
|
||||
如果这样不可能,又要求避免在不可信的或公共的网络上进行连接,请在 apiserver 和 kubelet 之间使用 [SSH 隧道](/docs/concepts/architecture/master-node-communication/#ssh-tunnels)。
|
||||
|
||||
|
||||
最后,应该启用[Kubelet 用户认证和/或权限认证](/docs/admin/kubelet-authentication-authorization/)来保护 kubelet API。
|
||||
|
||||
|
||||
### apiserver -> nodes, pods, and services
|
||||
|
||||
|
||||
从 apiserver 到 node、pod或者service 的连接默认为纯 HTTP 方式,因此既没有认证,也没有加密。他们能够通过给API URL 中的 node、pod 或 service 名称添加前缀 `https:` 来运行在安全的 HTTPS 连接上。但他们即不会认证 HTTPS endpoint 提供的证书,也不会提供客户端证书。这样虽然连接是加密的,但它不会提供任何完整性保证。这些连接**目前还不能安全的**在不可信的或公共的网络上运行。
|
||||
|
||||
|
||||
### SSH 隧道
|
||||
|
||||
|
||||
[Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/docs/) 使用 SSH 隧道保护 Master -> Cluster 通信路径。在这种配置下,apiserver 发起一个到集群中每个节点的 SSH 隧道(连接到在 22 端口监听的 ssh 服务)并通过这个隧道传输所有到 kubelet、node、pod 或者 service 的流量。这个隧道保证流量不会在集群运行的私有 GCE 网络之外暴露。
|
||||
@@ -0,0 +1,233 @@
|
||||
---
|
||||
approvers:
|
||||
- caesarxuchao
|
||||
- dchen1107
|
||||
|
||||
title: Nodes
|
||||
redirect_from:
|
||||
- "/docs/admin/node/"
|
||||
- "/docs/admin/node.html"
|
||||
- "/docs/concepts/nodes/node/"
|
||||
- "/docs/concepts/nodes/node.html"
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
|
||||
## Node 是什么?
|
||||
|
||||
|
||||
`Node` 是 Kubernetes 的工作节点,以前叫做 `minion`。取决于你的集群,Node 可以是一个虚拟机或者物理机器。每个 node 都有用于运行 [pods](/docs/user-guide/pods) 的必要服务,并由 master 组件管理。Node 上的服务包括 Docker、kubelet 和 kube-proxy。请查阅架构设计文档中 [The Kubernetes Node](https://git.k8s.io/community/contributors/design-proposals/architecture/architecture.md#the-kubernetes-node) 一节获取更多细节。
|
||||
|
||||
|
||||
## Node 状态
|
||||
|
||||
|
||||
一个 node 的状态包含以下信息:
|
||||
|
||||
* [地址](#地址)
|
||||
* ~~[阶段](#阶段)~~ **已废弃**
|
||||
* [条件](#条件)
|
||||
* [容量](#容量)
|
||||
* [信息](#信息)
|
||||
|
||||
|
||||
下面对每个章节进行详细描述。
|
||||
|
||||
|
||||
### 地址
|
||||
|
||||
|
||||
这些字段组合的用法取决于你的云服务商或者裸机配置。
|
||||
|
||||
* HostName:HostName 和 node 内核报告的相同。可以通过 kubelet 的 `--hostname-override` 参数覆盖。
|
||||
* ExternalIP:通常是可以外部路由的 node IP 地址(从集群外可访问)。
|
||||
* InternalIP:通常是仅可在集群内部路由的 node IP 地址。
|
||||
|
||||
|
||||
### 阶段
|
||||
|
||||
|
||||
一废弃:node 阶段已经不再使用。
|
||||
|
||||
|
||||
### 条件
|
||||
|
||||
|
||||
`conditions` 字段描述了所有 `Running` nodes 的状态。
|
||||
|
||||
|
||||
| Node 条件 | 描述 |
|
||||
| ---------------- | ---------------------------------------- |
|
||||
| `OutOfDisk` | `True` 表示 node 的空闲空间不足以用于添加新 pods, 否则为 `False` |
|
||||
| `Ready` | `True` 表示 node 是健康的并已经准备好接受 pods;`False` 表示 node 不健康而且不能接受 pods;`Unknown` 表示 node 控制器在最近 40 秒内没有收到 node 的消息 |
|
||||
| `MemoryPressure` | `True` 表示 node 不存在内存压力 -- 即 node 内存用量低, 否则为 `False` |
|
||||
| `DiskPressure` | `True` 表示 node 不存在磁盘压力 -- 即磁盘用量低, 否则为 `False` |
|
||||
|
||||
|
||||
Node 条件使用一个 JSON 对象表示。例如,下面的响应描述了一个健康的 node。
|
||||
|
||||
```json
|
||||
"conditions": [
|
||||
{
|
||||
"kind": "Ready",
|
||||
"status": "True"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
如果 Ready 条件处于状态 "Unknown" 或者 "False" 的时间超过了 `pod-eviction-timeout`(一个传递给 [kube-controller-manager](/docs/admin/kube-controller-manager/) 的参数),node 上的所有 Pods 都会被 Node 控制器计划删除。默认的删除超时时长为**5分钟**。某些情况下,当 node 不可访问时,apiserver 不能和其上的 kubelet 通信。删除 pods 的决定不能传达给 kubelet,直到它重新建立和 apiserver 的连接为止。与此同时,被计划删除的 pods 可能会继续在分区 node 上运行。
|
||||
|
||||
|
||||
在 1.5 版本之前的 Kubernetes 里,node 控制器会将不能访问的 pods 从 apiserver 中[强制删除](/docs/concepts/workloads/pods/pod/#force-deletion-of-pods)。但在 1.5 或更高的版本里,在node 控制器确认这些 pods 已经在集群里停运行前不会强制删除它们。你可以看到这些处于 "Terminating" 或者 "Unknown" 状态的 pods 可能在无法访问的 node 上运行。为了防止 kubernetes 不能从底层基础设施中推断出一个 node 是否已经永久的离开了集群,集群管理员可能需要手动删除这个 node 对象。从 Kubernetes 删除 node 对象将导致 apiserver 删除 node 上所有运行的 Pod 对象并释放它们的名字。
|
||||
|
||||
|
||||
### 容量
|
||||
|
||||
|
||||
描述 node 上的可用资源:CPU、内存和可以调度到 node 上的 pods 的最大数量。
|
||||
|
||||
|
||||
### 信息
|
||||
|
||||
|
||||
关于 node 的通用信息,例如内核版本、Kubernetes 版本(kubelet 和 kube-proxy 版本)、Docker 版本 (如果使用了)和 OS 名。这些信息由 Kubelet 从 node 搜集而来。
|
||||
|
||||
|
||||
## 管理
|
||||
|
||||
|
||||
与 [pods](/docs/user-guide/pods) 和 [services](/docs/user-guide/services) 不同,node 并不是在 Kubernetes 内部创建的:它是被外部的云服务商创建,例如 Google Compute Engine 或者你的集群中的物理或者虚拟机。这意味着当 Kubernetes 创建一个 node 时,它其实仅仅创建了一个对象来代表这个 node。创建以后,Kubernetes 将检查这个 node 是否可用。例如,如果你尝试使用如下内容创建一个 node:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "Node",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "10.240.79.157",
|
||||
"labels": {
|
||||
"name": "my-first-k8s-node"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Kubernetes 会在内部创一个 node 对象(象征 node),并基于 `metadata.name` 字段(我们假设 `metadata.name` 能够被解析)通过健康检查来验证 node。如果 node 可用,意即所有必要服务都已运行,它就符合了运行一个 pod 的条件;否则它将被所有的集群动作忽略直到变为可用。请注意,Kubernetes 将保存不可用 node 的对象,除非它被客户端显式的删除。Kubernetes 将持续检查 node 是否变的可用。
|
||||
|
||||
|
||||
当前,有3个组件同 Kubernetes node 接口交互:node 控制器、kubelet 和 kubectl。
|
||||
|
||||
|
||||
### Node 控制器
|
||||
|
||||
|
||||
Node 控制器是一个 Kubernetes master 组件,管理 nodes 的方方面面。
|
||||
|
||||
|
||||
Node 控制器在 node 的生命周期中扮演了多个角色。第一个是当 node 注册时为它分配一个 CIDR block(如果打开了 CIDR 分配)。
|
||||
|
||||
|
||||
第二个是使用云服务商提供了可用节点列表保持 node 控制器内部的 nodes 列表更新。如果在云环境下运行,任何时候当一个 node 不健康时 node 控制器将询问云服务 node 的虚拟机是否可用。如果不可用,node 控制器会将这个 node 从它的 nodes 列表删除。
|
||||
|
||||
|
||||
第三个是监控 nodes 的健康情况。Node 控制器负责在 node 不能访问时(也即是 node 控制器因为某些原因没有收到心跳,例如 node 宕机)将它的 NodeStatus 的 NodeReady 状态更新为 ConditionUnknown。后续如果 node 持续不可访问,Node 控制器将删除 node 上的所有 pods(使用优雅终止)。(默认情况下 40s 开始报告 ConditionUnknown,在那之后 5m 开始删除 pods。)Node 控制器每隔 `--node-monitor-period` 秒检查每个 node 的状态。
|
||||
|
||||
|
||||
在 Kubernetes 1.4 中我们更新了 node 控制器逻辑以更好的处理大批量 nodes 访问 master 出问题的情况(例如 master 的网络出了问题)。从 1.4 开始,node 控制器在决定删除 pod 之前会检查集群中所有 nodes 的状态。
|
||||
|
||||
|
||||
大部分情况下, node 控制器把删除频率限制在每秒 `--node-eviction-rate` 个(默认为 0.1)。这表示它在 10 秒钟内不会从超过一个 node 上删除 pods。
|
||||
|
||||
|
||||
当一个 availability zone 中的 node 变为不健康时,它的删除行为将发生改变。Node 控制器会同时检查 zone 中不健康(NodeReady 状态为 ConditionUnknown 或 ConditionFalse)的 nodes 的百分比。如果不健康 nodes 的部分超过 `--unhealthy-zone-threshold` (默认为 0.55),删除速率将会减小:如果集群较小(意即小于等于 `--large-cluster-size-threshold` 个 nodes - 默认为50),删除将会停止,否则删除速率将降为每秒 `--secondary-node-eviction-rate` 个(默认为 0.01)。在单个 availability zone 实施这些策略的原因是当一个 availability zone 可能从 master 分区时其它的仍然保持连接。如果你的集群没有跨越云服务商的多个 availability zones,那就只有一个 availability zone(整个集群)。
|
||||
|
||||
|
||||
在多个 availability zones 分布你的 nodes 的一个关键原因是当整个 zone 故障时,工作负载可以转移到健康的 zones。因此,如果一个 zone 中的所有 nodes 都不健康时,node 控制器会以正常的速率 `--node-eviction-rate` 删除。在所有的 zones 都不健康(也即集群中没有健康 node)的极端情况下,node 控制器将假设 master 的连接出了某些问题,它将停止所有删除动作直到一些连接恢复。
|
||||
|
||||
|
||||
从 Kubernetes 1.6 开始,NodeController 还负责删除运行在拥有 `NoExecute` taints 的 nodes 上的 pods,如果这些 pods 没有 tolerate 这些 taints。此外,作为一个默认禁用的 alpha 特性,NodeController 还负责根据 node 故障(例如 node 不可访问或没有 ready)添加 taints。请查看 [这个文档](/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature)了解关于 `NoExecute` taints 和这个 alpha 特性。
|
||||
|
||||
|
||||
### Nodes 自注册
|
||||
|
||||
|
||||
当 kubelet 标志 `--register-node` 为 true (默认)时,它会尝试向 API 服务注册自己。这是首选模式,被绝大多数发行版选用。
|
||||
|
||||
|
||||
对于自注册模式,kubelet 使用下列参数启动:
|
||||
|
||||
- `--api-servers` - apiservers 地址。
|
||||
- `--kubeconfig` - 用于向 apiserver 验证自己的凭据路径。
|
||||
- `--cloud-provider` - 如何从云服务商读取关于自己的元数据。
|
||||
- `--register-node` - 自动向 API 服务注册。
|
||||
- `--register-with-taints` - 使用 taints 列表(逗号分隔的 `<key>=<value>:<effect>`)注册 node。当 `register-node` 为 false 时无效。
|
||||
- `--node-ip` - node IP 地址。
|
||||
- `--node-labels` - 向集群注册时给 node 添加的 labels。
|
||||
- `--node-status-update-frequency` - 指定 kubelet 向 master 发送状态的频率。
|
||||
|
||||
|
||||
目前,任何 kubelet 都被授权可以创建/修改任意 node 资源,但通常只对自己的进行创建/修改。(未来我们计划只允许一个 kubelet 修改它自己 node 的资源。)
|
||||
|
||||
|
||||
#### 手动 Node 管理
|
||||
|
||||
|
||||
集群管理员可以创建及修改 node 对象。
|
||||
|
||||
|
||||
如果管理员希望手动创建 node 对象,请设置 kubelet 标记 `--register-node=false`。
|
||||
|
||||
|
||||
管理员可以修改 node 资源(忽略 `--register-node` 设置)。修改包括在 node 上设置 labels及标记它为不可调度。
|
||||
|
||||
|
||||
Nodes 上的 labels 可以和 pods 的 node selectors 一起使用来控制调度,例如限制一个 pod 只能在一个符合要求的 nodes 子集上运行。
|
||||
|
||||
|
||||
标记一个 node 为不可调度的将防止新建 pods 调度到那个 node 之上,但不会影响任何已经在它之上的 pods。这是重启 node 等操作之前的一个有用的准备步骤。例如,标记一个 node 为不可调度的,执行以下命令:
|
||||
|
||||
```shell
|
||||
kubectl cordon $NODENAME
|
||||
```
|
||||
|
||||
|
||||
请注意,被 daemonSet 控制器创建的 pods 将忽略 Kubernetes 调度器,且不会遵照 node 上不可调度的属性。这个假设基于守护程序属于节点机器,即使在准备重启而隔离应用的时候。
|
||||
|
||||
|
||||
### Node 容量
|
||||
|
||||
|
||||
Node 的容量(cpu 数量和内存容量)是 node 对象的一部分。通常情况下,在创建 node 对象时,它们会注册自己并报告自己的容量。如果你正在执行[手动 node 管理](#manual-node-administration),那么你需要在添加 node 时手动设置 node 容量。
|
||||
|
||||
|
||||
Kubernetes 调度器保证一个 node 上有足够的资源供其上的所有 pods 使用。它会检查 node 上所有容器要求的总和不会超过 node 的容量。这包括所有 kubelet 启动的容器,但不包含 Docker 启动的容器和不在容器中的进程。
|
||||
|
||||
|
||||
如果希望显式的为非 pod 进程预留资源,你可以创建一个占位 pod。使用如下模板:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: resource-reserver
|
||||
spec:
|
||||
containers:
|
||||
- name: sleep-forever
|
||||
image: k8s.gcr.io/pause:0.8.0
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
```
|
||||
|
||||
|
||||
设置 `cpu` 和 `memory` 值为你希望预留的资源量。将文件放在清单文件夹中(kubelet 的 `--config=DIR` 标志)。当你希望预留资源时,在每个 kubelet 上都这样执行。
|
||||
|
||||
|
||||
## API 对象
|
||||
|
||||
|
||||
Node 是 Kubernetes REST API 的顶级资源。更多关于 API 对象的细节可以在这里找到: [Node API
|
||||
object](/docs/api-reference/{{< param "version" >}}/#node-v1-core).``
|
||||
Reference in New Issue
Block a user