1 Node
Node 是 Kubernetes 集群的工作节点,可以是物理机也可以是虚拟机。
1.1 Node 状态
Node 包括如下状态信息:
- Address
- HostName:可以被 kubelet 中的
--hostname-override参数替代。 - ExternalIP:可以被集群外部路由到的 IP 地址。
- InternalIP:集群内部使用的 IP,集群外部无法访问。
- HostName:可以被 kubelet 中的
- Condition
- OutOfDisk:磁盘空间不足时为
True - Ready:Node controller 40 秒内没有收到 node 的状态报告为
Unknown,健康为True,否则为False。 - MemoryPressure:当 node 有内存压力时为
True,否则为False。 - DiskPressure:当 node 有磁盘压力时为
True,否则为False。
- OutOfDisk:磁盘空间不足时为
- Capacity
- CPU
- 内存
- 可运行的最大 Pod 个数
- Info:节点的一些版本信息,如 OS、kubernetes、docker 等
1.2 Node 上 Pod 管理
禁止 Pod 调度到该节点上。
kubectl cordon <node>驱逐该节点上的所有 Pod。
kubectl drain <node>该命令会删除该节点上的所有 Pod(DaemonSet 除外),在其他 node 上重新启动它们,通常该节点需要维护时使用该命令。直接使用该命令会自动调用 kubectl cordon <node> 命令。当该节点维护完成,启动了 kubelet 后,再使用 kubectl uncordon <node> 即可将该节点添加到 kubernetes 集群中。
1.3 Node 命令
kubectl get nodes2 Namespace
Namespace,命名空间,用于多套环境的资源隔离或者多租户的资源隔离。
- 多环境的资源隔离
- 默认情况下,pod 之间可相互访问。使用 namespace 可以将访问隔离,形成逻辑上的“组”。
- 多租户的资源隔离
- 将不同的 namespace 交给不同的租户管理,从而实现租户的资源隔离。还可以结合 K8S 的资源配额机制,限定不同租户能占用的资源,如 CPU、内存使用量,来实现租户可用资源的管理。
kubernetes 在集群启动之后,会默认创建几个 namespace.
[root@master ~]# kubectl get namespace
NAME STATUS AGE
default Active 45h # 所有未指定Namespace的对象都会被分配在default命名空间
kube-node-lease Active 45h # 集群节点之间的心跳维护,v1.13开始引入
kube-public Active 45h # 此命名空间下的资源可以被所有人访问(包括未认证用户)
kube-system Active 45h # 所有由Kubernetes系统创建的资源都处于这个命名空间ns 的名字需要符合 [a-z0-9]([-a-z0-9]*[a-z0-9])? 不能有下划线.

2.1 Namespace 命令
# 查看所有的命名空间
kubectl get namespaces
kubectl get ns
# 查看指定命名空间
kubectl get ns default
# 查看指定命名空间 - yaml 格式 (特定格式 wide、json、yaml)
kubectl get ns default -o yaml
# 查看指定命名空间 - wide 格式(一行的形式展示相信信息)
kubectl get ns default -o yaml
# 查看命名空间详情
kubectl describe ns default
# 创建命名空间
kubectl create ns dev
# 删除命名空间
kubectl delete ns dev
# 基于 yaml 创建命名空间
kubectl apply -f dev.yaml
# 基于 yaml 删除命名空间
kubectl delete -f dev.yaml
# yaml 配置文件
apiVersion: v1
kind: Namespace
metadata:
name: dev3 Label
3.1 Label
Label 的目标 —— 便于微服务的管理:
- “release” : “stable, “release” : “canary”
- “environment” : “dev”, “environment” : “qa”
- “tier” : “frontend”, “tier” : “backend”, “tier” : “cache”
- “partition” : “customerA”, “partition” : “customerB”
- “track” : “daily”, “track” : “weekly”
- “team” : “teamA”,“team:” : “teamB”`
Label 编写要求:
- Label key 的组成:
- 不得超过 63 个字符
- 可以使用前缀,使用 / 分隔,前缀必须是 DNS 子域,不得超过 253 个字符,系统中的自动化组件创建的 label 必须指定前缀,
kubernetes.io/由 kubernetes 保留 - 起始必须是字母(大小写都可以)或数字,中间可以有连字符、下划线和点
- Label value 的组成:
- 不得超过 63 个字符
- 起始必须是字母(大小写都可以)或数字,中间可以有连字符、下划线和点
# 为 pod 资源打标签
kubectl label pod nginx-pod version=1.0 -n dev
# 为 pod 资源更新标签
kubectl label pod nginx-pod version=2.0 -n dev --overwrite
# 查看标签
kubectl get pod nginx-pod -n dev --show-labels
# 查看 version 标签
kubectl get pod -L version
# 筛选标签
kubectl get pod -n dev -l version=2.0 --show-labels
kubectl get pod -n dev -l version!=2.0 --show-labels
#删除标签
kubectl label pod nginx-pod version- -n devapiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
labels:
version: "3.0"
env: "test"
spec:
containers:
- image: nginx:latest
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP3.2 Label Selector
Label selector
通过 label selector,客户端/用户可以指定一个 object 集合,通过 label selector 对 object 的集合进行操作。标签的选择条件可以使用多个,此时将多个 Label Selector 进行组合,使用逗号”,“进行分隔即可。
Label selector 有两种类型:
- equality-based :可以使用 =、==、!= 操作符,可以使用逗号分隔多个表达式
- set-based :可以使用 in、notin、! 操作符,另外还可以没有操作符,直接写出某个 label 的 key,表示过滤有某个 key 的 object 而不管该 key 的 value 是何值,! 表示没有该 label 的 object
kubectl get pods -l environment=production,tier=frontend
kubectl get pods -l 'environment in (production),tier in (frontend)'
kubectl get pods -l 'environment in (production, qa)'
kubectl get pods -l 'environment,environment notin (frontend)'API object 中设置 Label Selector:
在 service、replicationcontroller 等 object 中有对 pod 的 label selector,使用方法只能使用等于操作,例如:
selector:
component: redis在 Job、Deployment、ReplicaSet 和 DaemonSet 这些 object 中,支持 set-based 的过滤,例如:
selector:
matchLabels:
component: redis
matchExpressions:
- { key: tier, operator: In, values: [cache] }
- { key: environment, operator: NotIn, values: [dev] }另外在 node affinity 和 pod affinity 中的 label selector 的语法又有些许不同,示例如下:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- e2e-az2
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value4 Annotation
Annotation 和 Label 类似,但是面向的受众不同。Label 主要面向 K8S 系统,K8S 系统根据 Label 进行多个 pod 管理等。Annotation 面向使用者,类似于代码中的注释,提供说明。例如,Owner 信息、构建、发布或镜像信息(如时间戳、发布 ID、Git 分支、PR 数量、镜像哈希、仓库地址)等。
注解和标签一样,是键/值对。注解中的元数据,可以很小,也可以很大,可以是结构化的,也可以是非结构化的,能够包含标签不允许的字符。
注解(Annotations) 存储的形式是键/值对。有效的注解键分为两部分: 可选的前缀和名称,以斜杠(/)分隔。 名称段是必需项,并且必须在 63 个字符以内,以字母数字字符([a-z0-9A-Z])开头和结尾, 并允许使用破折号(-),下划线(_),点(.)和字母数字。 前缀是可选的。如果指定,则前缀必须是 DNS 子域:一系列由点(.)分隔的 DNS 标签, 总计不超过 253 个字符,后跟斜杠(/)。 如果省略前缀,则假定注解键对用户是私有的。 由系统组件添加的注解 (例如,kube-scheduler,kube-controller-manager,kube-apiserver,kubectl 或其他第三方组件),必须为终端用户添加注解前缀。
kubectl annotate svc nginx -n devops kubemaster.top/owner=@marionxue

5 垃圾收集 - N
6 资源调度 - N
Kubernetes 中有一个叫做 kube-scheduler 的组件,该组件就是通过 K8S 的监测 Watch 专门监听 kube-apiserver 中是否有还未调度到 node 上的 pod,再通过特定的算法为 pod 指定分派 node 运行。
kube-scheduler 在设计上允许你自己编写一个调度组件并替换原有的 kube-scheduler。在做调度决定时需要考虑的因素包括:单独和整体的资源请求、硬件/软件/策略限制、 亲和以及反亲和要求、数据局部性、负载间的干扰等等。
Kubernetes 中的众多资源类型,例如 Deployment、DaemonSet、StatefulSet 等都已经定义了 Pod 运行的一些默认调度策略,但是如果我们细心的根据 node 或者 pod 的不同属性,分别为它们打上标签之后,我们将发现 Kubernetes 中的高级调度策略是多么强大。当然如果要实现动态的资源调度,即 pod 已经调度到某些节点上后,因为一些其它原因,想要让 pod 重新调度到其它节点。
考虑以下两种情况:
- 集群中有新增节点,想要让集群中的节点的资源利用率比较均衡一些,想要将一些高负载的节点上的 pod 驱逐到新增节点上,这是 kuberentes 的 scheduler 所不支持的,需要使用如 descheduler 这样的插件来实现。
- 想要运行一些大数据应用,设计到资源分片,pod 需要与数据分布达到一致均衡,避免个别节点处理大量数据,而其它节点闲置导致整个作业延迟,这时候可以考虑使用 kube-batch。
kube-sheduler 中的节点选择
kube-scheduler 给一个 Pod 做调度选择时包含两个步骤 —— 过滤和打分。过滤:选出所有满足 pod 调度需求的节点。打分:从所有可调度节点中,选择最合适的节点,若存在多个,则随机选择。
支持以下两种方式配置调度器的过滤和打分行为:
- 调度策略 允许你配置过滤所用的 断言(Predicates) 和打分所用的 优先级(Priorities)。
- 调度配置 允许你配置实现不同调度阶段的插件,包括:
QueueSort、Filter、Score、Bind、Reserve、Permit等等。你也可以配置 kube-scheduler 运行不同的配置文件。
接下来阅读
- 阅读关于调度器性能调优
- 阅读关于 Pod 拓扑分布约束
- 阅读关于 kube-scheduler 的参考文档
- 阅读 kube-scheduler 配置参考 (v1beta3)
- 了解关于配置多个调度器 的方式
- 了解关于拓扑结构管理策略
- 了解关于 Pod 开销
- 了解关于如何在以下情形使用卷来调度 Pod:
7 服务质量等级 QoS
QoS(Quality of Service),大部分译为“服务质量等级”,又译作“服务质量保证”,是作用在 Pod 上的一个配置,当 Kubernetes 创建一个 Pod 时,它就会给这个 Pod 分配一个 QoS 等级,可以是以下等级之一:
- Guaranteed:Pod 里的每个容器都必须有内存/CPU 限制和请求,而且值必须相等。
- Burstable:Pod 里至少有一个容器有内存或者 CPU 请求且不满足 Guarantee 等级的要求,即内存/CPU 的值设置的不同。
- BestEffort:容器必须没有任何内存或者 CPU 的限制或请求。
该配置不是通过一个配置项来配置的,而是通过配置 CPU/内存的 limits 与 requests 值的大小来确认服务质量等级的。使用 kubectl get pod -o yaml 可以看到 pod 的配置输出中有 qosClass 一项。该配置的作用是为了给资源调度提供策略支持,调度算法根据不同的服务质量等级可以确定将 pod 调度到哪些节点上。
例如,下面这个 YAML 配置中的 Pod 资源配置部分设置的服务质量等级就是 Guarantee。
spec:
containers:
...
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi下面的 YAML 配置的 Pod 的服务质量等级是 Burstable。
spec:
containers:
...
resources:
limits:
memory: "180Mi"
requests:
memory: "100Mi"