K8S的整体结构图
k8s对象
在 Kubernetes 系统中,Kubernetes 对象是持久化的实体。 Kubernetes 使用这些实体去表示整个集群的状态。 具体而言,它们描述了如下信息:
- 哪些容器化应用正在运行(以及在哪些节点上运行)
- 可以被应用使用的资源
- 关于应用运行时行为的策略,比如重启策略、升级策略以及容错策略
Kubernetes 对象是一种“意向表达(Record of Intent)”。一旦创建该对象, Kubernetes 系统将不断工作以确保该对象存在。通过创建对象,你本质上是在告知
Kubernetes 系统,你想要的集群工作负载状态看起来应是什么样子的, 这就是 Kubernetes 集群所谓的期望状态(Desired State)。
操作 Kubernetes 对象 —— 无论是创建、修改或者删除 —— 需要使用 Kubernetes API。 比如,当使用 kubectl
命令行接口(CLI)时,CLI 会调用必要的 Kubernetes API; 也可以在程序中使用客户端库, 来直接调用 Kubernetes API。
对象规约(Spec)与状态(Status)
几乎每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置: 对象 spec
(规约) 和对象 status
(状态)。 对于具有 spec
的对象,你必须在创建对象时设置其内容,描述你希望对象所具有的特征: 期望状态(Desired State)。
status
描述了对象的当前状态(Current State),它是由 Kubernetes 系统和组件设置并更新的。在任何时刻,Kubernetes 控制平面 都一直在积极地管理着对象的实际状态,以使之达成期望状态。
例如,Kubernetes 中的 Deployment 对象能够表示运行在集群中的应用。 当创建 Deployment 时,你可能会设置 Deployment 的 spec
,指定该应用要有 3 个副本运行。 Kubernetes 系统读取 Deployment 的 spec
, 并启动我们所期望的应用的 3 个实例 —— 更新状态以与规约相匹配。 如果这些实例中有的失败了(一种状态变更),Kubernetes 系统会通过执行修正操作来响应 spec
和 status
间的不一致 —— 意味着它会启动一个新的实例来替换。
描述 Kubernetes 对象
创建 Kubernetes 对象时,必须提供对象的 spec
,用来描述该对象的期望状态, 以及关于对象的一些基本信息(例如名称)。 当使用 Kubernetes API 创建对象时(直接创建或经由 kubectl
创建), API 请求必须在请求主体中包含 JSON 格式的信息。 大多数情况下,你需要提供 .yaml
文件为 kubectl 提供这些信息。 kubectl
在发起 API 请求时,将这些信息转换成 JSON 格式。
这里有一个 .yaml
示例文件,展示了 Kubernetes Deployment 的必需字段和对象 spec
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # 告知 Deployment 运行 2 个与该模板匹配的 Pod
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
这是一个用于创建Deployment对象的Kubernetes配置文件。让我们逐个字段进行解析:
apiVersion: apps/v1:
这是指定使用的Kubernetes API版本。在这个配置中,使用了apps/v1版本,表示我们将使用apps API组中的v1版本来创建Deployment对象。kind: Deployment:
这定义了要创建的Kubernetes对象的类型,这里是一个Deployment对象。metadata:
这是Deployment对象的元数据部分,用于定义对象的名称等信息。
- name: nginx-deployment:
这是Deployment对象的名称,被设置为"nginx-deployment"。
- spec:
这是Deployment对象的规约部分,描述了期望的状态和配置。
selector:
该字段用于标记将由Deployment控制的Pod。在这里,使用matchLabels来选择拥有标签"app: nginx"的Pod。replicas: 2:
这指定Deployment所需的Pod副本数为2个。Deployment会确保集群中始终有两个与该模板匹配的Pod在运行,如果Pod数少于2,它会自动创建新的Pod以达到所需的数量。template:
这是Pod模板,描述了要创建的Pod的配置。
metadata:
这里是Pod的元数据部分。
- labels:
这里定义了Pod的标签,标签"app: nginx"与上面的selector匹配,使得Deployment能够控制这些Pod。spec:
这是Pod的规约部分,描述了Pod的具体配置。
containers:
这是Pod中的容器部分。
name: nginx:
容器的名称被设置为"nginx"。image: nginx:1.14.2:
这是要使用的nginx镜像及其版本。ports:
这里定义了容器的端口配置。
- containerPort: 80:
容器将监听80端口,使得能够通过该端口访问nginx服务。以上配置文件描述了一个名为"nginx-deployment"的Deployment对象,它控制运行两个nginx容器副本,并通过标签"app: nginx"来选择这些Pod。每个Pod都包含一个名为"nginx"的容器,使用nginx:1.14.2镜像,并在容器内监听80端口。
相较于上面使用 .yaml
文件来创建 Deployment,另一种类似的方式是使用 kubectl
命令行接口(CLI)中的 kubectl apply
命令, 将 .yaml
文件作为参数。下面是一个示例:
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
输出类似下面这样:
deployment.apps/nginx-deployment created
必需字段
在想要创建的 Kubernetes 对象所对应的 .yaml
文件中,需要配置的字段如下:
apiVersion
- 创建该对象所使用的 Kubernetes API 的版本kind
- 想要创建的对象的类别metadata
- 帮助唯一标识对象的一些数据,包括一个name
字符串、UID
和可选的namespace
spec
- 你所期望的该对象的状态
对每个 Kubernetes 对象而言,其 spec
之精确格式都是不同的,包含了特定于该对象的嵌套字段。 Kubernetes API 参考可以帮助你找到想要使用 Kubernetes 创建的所有对象的规约格式。
例如,参阅 Pod API 参考文档中
spec
字段。 对于每个 Pod,其.spec
字段设置了 Pod 及其期望状态(例如 Pod 中每个容器的容器镜像名称)。 另一个对象规约的例子是 StatefulSet API 中的spec
字段。 对于 StatefulSet 而言,其.spec
字段设置了 StatefulSet 及其期望状态。 在 StatefulSet 的.spec
内,有一个为 Pod 对象提供的模板。 该模板描述了 StatefulSet 控制器为了满足 StatefulSet 规约而要创建的 Pod。 不同类型的对象可以有不同的.status
信息。API 参考页面给出了.status
字段的详细结构, 以及针对不同类型 API 对象的具体内容。
label(标签)
在Kubernetes(K8s)中,label是用来附着到资源对象(如Pod、Node、Service等)上的键值对。它是一种元数据,允许您对资源进行更灵活的组织、查询和选择。下面是一些关于Kubernetes中label的详细解释:
-
什么是Label:
-
•
Label是键值对(key-value pair)的元数据,附着在Kubernetes资源对象上。
-
•
Label不是唯一标识符,多个资源可以共享相同的label。
-
-
Label的作用:
-
•
组织和选择: Labels可以用来组织和选择资源对象。您可以使用label选择器(label selectors)来筛选出具有特定label的资源。
-
•
路由和调度: Labels可以用于定义服务的路由规则,也可用于调度Pod到特定的Node。
-
-
Label的语法:
-
•
Label的键和值都是字符串。
-
•
label键可以包含斜杠(
/
),但是一些工具可能不支持这种形式。
-
-
Label的附着:
-
•
Label可以在资源创建时附着,也可以在后期修改。
-
•
使用
kubectl
命令行工具或Kubernetes API可以对资源添加或删除label。
-
-
Label选择器:
-
•
Label选择器是一种通过label对资源进行查询的机制。
-
•
通过使用
kubectl
或在Pod定义中指定nodeSelector
字段,您可以选择特定label的Pod或Node。
-
-
使用Label的例子:
-
•
Pod调度: 使用Node的label和Pod的
nodeSelector
字段,可以实现将Pod调度到具有特定属性的Node上。 -
•
服务路由: 使用Service的label和Ingress Controller,可以实现基于label的服务路由。
-
下面是一个Pod定义的示例,其中使用了label和nodeSelector
字段:
apiVersion: v1
kind: Pod
metadata:
name: mypod
labels:
app: myapp
tier: frontend
spec:
containers:
- name: mycontainer
image: nginx
nodeSelector:
size: Large
在这个例子中,Pod有两个label:app: myapp
和tier: frontend
。它还通过nodeSelector
字段指定,只能调度到拥有label size: Large
的Node上。
总体来说,Kubernetes中的label是一项非常有用的功能,使得资源的组织、查询和选择变得更加灵活。
nodeSelector
在 Kubernetes 中,nodeSelector
是一种用于将 Pod 调度到特定节点的机制。通过 nodeSelector
,你可以根据节点上的标签进行选择,以确保 Pod 被调度到符合条件的节点上。
以下是 nodeSelector
的详解:
基本语法: nodeSelector
被定义在 Pod 的规范(spec
)中,它是一个键值对的映射,其中键是节点标签的键,值是节点标签的值。
nodeSelector:
key: value
示例: 假设你的节点上有一个标签 size
,你可以使用 nodeSelector
将 Pod 调度到具有特定 size
值的节点上。
nodeSelector:
size: Large
上述配置表示 Pod 将只会被调度到具有标签 size=Large
的节点上。
多个条件: 你可以使用多个键值对来定义多个条件,这样 Pod 将仅在节点满足所有条件时被调度。
nodeSelector:
size: Large
environment: production
上述配置表示 Pod 将只会被调度到同时具有标签 size=Large
和 environment=production
的节点上。
查看所有节点及其标签:
这个命令将列出所有节点以及它们的标签
kubectl get nodes --show-labels
查看特定节点的标签:
kubectl get node <node-name> --show-labels
节点选择器和标签的设置: 在将 Pod 调度到节点上之前,确保节点上已经设置了相应的标签。你可以使用 kubectl label nodes <node-name> <label-key>=<label-value>
命令为节点设置标签。
kubectl label nodes node-1 size=Large
删除标签:
kubectl label nodes k8snode1 size-
更改标签值:
kubectl label nodes k8snode1 size=Large --overwrite
如果更改
size
这个标签的值,可以使用kubectl label
命令,并指定--overwrite=true
参数
存在性检查: 你还可以使用 exists
来检查节点是否具有某个标签。
nodeSelector:
size: Exists
上述配置表示 Pod 将只会被调度到具有任何 size
标签的节点上。
nodeSelector
提供了一种简单而有效的方式,通过标签条件将 Pod 调度到特定节点。这对于在节点上部署特定类型的工作负载或应用程序非常有用。