这篇文章主要介绍Kubernetes 对象的一些基本知识。通过本章的学习,可以能够初步的使用k8s平台,有初步认识yaml文件的能力,能够从感官上认识k8s。本文主要摘自k8s的官方文档,但是官方文档由翻译而成,有些地方说的不是人话,再次加上个人的理解,希望能够把大家带进k8s的世界。

一. 理解Kubernetes 对象

在 Kubernetes 系统中,Kubernetes 对象 是持久化的实体。 它使用这些实体去表示整个集群的状态。具体描述对象有:

  • 哪些容器化应用在运行(以及在哪些节点上)
  • 可以被应用使用的资源
  • 关于应用运行时表现的策略,比如重启策略、升级策略,以及容错策略

在k8s对象中一个关键的名词。期望状态(Desired State),具体解释为Kubernetes 对象一旦被创建,系统将持续工作以确保对象存在。通过创建对象,本质上是在告知 Kubernetes 系统,所需要的集群工作负载看起来是什么样子的​​​​​​。无论是创建、修改,或者删除 等方式操作k8s对象,都需要通过 Kubernetes API ,比如使用kubectl命令行接口,LI 会执行必要的 Kubernetes API 调用, 也可以在程序中使用客户端库直接调用 Kubernetes API。

1. 对象规约(Spec)与对象状态(Status)

k8s包含两个负责管理对象的配置字段:对象规约(Spec)与对象状态(Status)。对象规约在创建时候设置其内容,描述对象所具有的特征,也就是上文所说的期望状态;而对象状态由 Kubernetes 系统和组件 设置并更新。控制平面一直监控对象的实际状态,以使之与期望状态相匹配。例如,Kubernetes 中的 Deployment 对象能够表示运行在集群中的应用。 当创建 Deployment 时,需要设置 Deployment 的 spec,指定该应用需要有 3 个副本运行。 Kubernetes 系统读取 Deployment 规约,并启动我们所期望的应用的 3 个实例 。 如果这些实例中有的失败了(一种状态变更),Kubernetes 系统通过执行修正操作 来响应规约和状态间的不一致。

2. 描述Kubernetes 对象

创建 Kubernetes 对象时,必须提供对象的规约,用来描述该对象的期望状态, 以及关于对象的一些基本信息。使用 Kubernetes API 创建对象时,API 请求必须在请求体中包含 JSON 格式的信息。但大多数情况都是yaml文件。kubectl在发起 API 请求时,将这些信息转换成 JSON 格式。

#简单的ngix-deployment实例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

可以采用命令将yaml文件部署

kubectl apply -f nginx-deployment.yaml

输出类似如下这样:

deployment.apps/nginx-deployment created

3. 必须的字段

创建的 Kubernetes 对象对应的 yaml 文件中,必须有以下三个字段:

  • apiVersion - 创建该对象所使用的 Kubernetes API 的版本
  • kind - 想要创建的对象的类别
  • metadata - 帮助唯一性标识对象的一些数据,包括一个 name 字符串、UID 和可选的 namespace

当然spec也是必不可少的,在后续的文章中详细讲yaml文件的具体编写。

二. Kubernetes 对象管理

kubectl命令行工具提供了多种方式管理Kubernetes 对象。本文主要概述三种不同的方式,具体kubectl命令参数,我将专门写一篇文章来讲。

1.命令式

使用命令式命令时,用户可以在集群中的活动对象上进行操作。用户将以参数的方式将操作传给kubectl。这种方式只能运行简单的任务,只在活动的对象上操作,不提供给之前的历史记录。

实例:

#通过创建 Deployment 对象来运行 nginx 容器的实例:
kubectl run nginx --image nginx

#用create 创建
kubectl create deployment nginx --image nginx

对比:

与对象配置相比的优点:

  • 命令简单,易学且易于记忆。
  • 命令仅需一步即可对集群进行更改

与对象配置相比的缺点:

  • 命令不与变更审查流程集成。
  • 命令不提供与更改关联的审核跟踪。
  • 除了实时内容外,命令不提供记录源。
  • 命令不提供用于创建新对象的模板。

2. 命令式对象配置

在命令式对象配置中,kubectl 命令指定操作(创建,替换等),可选标志和至少一个文件名。指定的文件必须包含 YAML 或 JSON 格式的对象的完整定义

实例:

#创建配置文件中定义的对象:
kubectl create -f nginx.yaml

#删除两个配置文件中定义的对象:
kubectl delete -f nginx.yaml -f redis.yaml

#通过覆盖活动配置来更新配置文件中定义的对象:
kubectl replace -f nginx.yaml


### 注意 !!!

replace 命令式命令将现有规范替换为新提供的规范,并删除对配置文件中缺少的对象的所有更改。此方法不应与规范独立于配置文件进行更新的资源类型一起使用。比如类型为 LoadBalancer 的服务,它的 externalIPs 字段就是独立于集群配置进行更新

对比:

与命令式命令相比的优点:

  • 对象配置可以存储在源控制系统中,比如 Git。
  • 对象配置可以与流程集成,例如在推送和审计之前检查更新。
  • 对象配置提供了用于创建新对象的模板。

与声明式对象配置相比的优点:

  • 命令式对象配置行为更加简单易懂。
  • 从 Kubernetes 1.5 版本开始,命令式对象配置更加成熟。

与命令式命令相比的缺点:

  • 对象配置需要对对象架构有基本的了解。
  • 对象配置需要额外的步骤来编写 YAML 文件。

与声明式对象配置相比的缺点:

  • 命令式对象配置更适合文件,而非目录。
  • 对活动对象的更新必须反映在配置文件中,否则会在下一次替换时丢失。

 

3. 声明式对象配置

使用声明式对象配置时,用户对本地存储的对象配置文件进行操作,但是用户未定义要对该文件执行的操作。kubectl会自动检测每个文件的创建、更新和删除操作。这使得配置可以在目录上工作,根据目录中配置文件对不同的对象执行不同的操作。简单的说声明式对象配置保留其他编写者所做的修改,即使这些更改并未合并到对象配置文件中。可以通过使用 patch API 操作仅写入观察到的差异,而不是使用 replace API 操作来替换整个对象配置来实现。

实例:

#处理 configs 目录中的所有对象配置文件,创建并更新活动对象。可以首先使用 diff 子命令查看将要进行的更改,然后在进行应用
kubectl diff -f configs/
kubectl apply -f configs/

#递归处理目录:
kubectl diff -R -f configs/
kubectl apply -R -f configs/

对比:

与命令式对象配置相比的优点:

  • 对活动对象所做的更改即使未合并到配置文件中,也会被保留下来。
  • 声明性对象配置更好地支持对目录进行操作并自动检测每个文件的操作类型(创建,修补,删除)。

与命令式对象配置相比的缺点:

  • 声明式对象配置难于调试并且出现异常时结果难以理解。
  • 使用 diff 产生的部分更新会创建复杂的合并和补丁操作。

 

4. create 和apply 的差异

说了那么多不是人能理解的话,我简单的把这两个参数的差异说下,在实际当中没有特别明确在什么时候要用哪个命令,主要看使用人的具体习惯。但是懂得了这个和别人对喷时候可用用的着,仅此而已。

序号kubectl applykubectl create
1根据yaml文件中包含的字段(yaml文件可以只写需要改动的字段),直接升级集群中的现有资源对象首先删除集群中现有的所有资源,然后重新根据yaml文件(必须是完整的配置信息)生成新的资源对象
2yaml文件可以不完整,只写需要的字段yaml文件必须是完整的配置字段内容
3kubectl apply只工作在yaml文件中的某些改动过的字段kubectl create工作在yaml文件中的所有字段
4在只改动了yaml文件中的某些声明时,而不是全部改动,你可以使用kubectl apply在没有改动yaml文件时,使用同一个yaml文件执行命令kubectl replace,将不会成功(fail掉),因为缺少相关改动信息

 

三.对象名称和 IDs

k8s中的每一个对象都有一个名称来标识在同类资源中的唯一性;且每个对象用UID来标识在整个集群中的唯一性。比如,在同一个名字空间中有一个名为 myapp-1234 的 Pod, 但是可以命名一个 Pod 和一个 Deployment 同为 myapp-1234.对于用户提供的非唯一性的属性,那是Kubernetes 提供了标签(Labels)和注解(Annotation)机制。

1. 名称

在客户端提供的字符串是引用资源 url 中的对象,如/api/v1/pods/name。像这样对象的名称是暂时的,如果删除该对象,则可以创建同名的新对象。比较常见的资源命名约束有三种:

DNS 子域名

很多资源类型需要可以用作 DNS 子域名的名称。需要满足以下规则:

  • 不能超过253个字符
  • 只能包含字母数字,以及'-' 和 '.'
  • 须以字母数字开头及结尾

DNS 标签名

DNS 标签标准需要满足以下条件:

  • 不能超过263个字符
  • 只能包含字母数字,以及'-' 
  • 须以字母数字开头及结尾

路径分段名称

某些资源类型要求名称能被安全地用作路径中的片段,名称不能是 ...,也不可以包含 / 或 % 这些字符。

使用配置清单举例如下:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-demo
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

 

2. UIDs

Kubernetes 系统生成唯一标识对象的字符串,在k8s的整个生命周期中创建的每个对象都有一个不同的 uid,用来区分类似实体的历史事件。Kubernetes UIDs 是全局唯一标识符(也叫 UUIDs

 

四. 名字空间

Kubernetes 支持多个虚拟集群,它们底层依赖于同一个物理集群。 这些虚拟集群被称为名字空间。

1. 名称空间用途

名字空间适用于存在很多跨多个团队或项目的用户的场景。如果只有几个或者十几个用户那名称空间也没使用的必要。名字空间为名称提供了一个范围,资源的名称需要在名字空间内是唯一的,但不能跨名字空间。 名字空间不能相互嵌套,每个 Kubernetes 资源只能在一个名字空间中,他是名字空间是在多个用户之间划分集群资源的一种方法。

2. 名称空间的用法

查看名称空间

kubectl get namespace

#结果为

NAME          STATUS    AGE
default       Active    1d
kube-node-lease   Active   1d
kube-system   Active    1d
kube-public   Active    1d

Kubernetes 会创建四个初始名字空间:

  • default 没有指明使用其它名字空间的对象所使用的默认名字空间
  • kube-system Kubernetes 系统创建对象所使用的名字空间
  • kube-public 这个名字空间是自动创建的,所有用户(包括未经过身份验证的用户)都可以读取它。 这个名字空间主要用于集群使用,以防某些资源在整个集群中应该是可见和可读的。 这个名字空间的公共方面只是一种约定,而不是要求。
  • kube-node-lease 此名字空间用于与各个节点相关的租期(Lease)对象; 此对象的设计使得集群规模很大时节点心跳检测性能得到提升

设置当前请求名称空间

kubectl run nginx --image=nginx --namespace=<名字空间名称>
kubectl get pods --namespace=<名字空间名称>

设置名称空间上下文

kubectl config set-context --current --namespace=<名字空间名称>
# 验证
kubectl config view | grep namespace:

3.名称空间和DNS

当你创建一个服务时, Kubernetes 会创建一个相应的DNS条目。该条目的形式是 <服务名称>.<名字空间名称>.svc.cluster.local,如果容器只使用 <服务名称>,它将被解析到本地名字空间的服务。这对于跨多个名字空间(如开发、分级和生产) 使用相同的配置非常有用。

 

##注意:并非所有对象都在名字空间中

大多数 kubernetes 资源(例如 Pod、Service、副本控制器等)都位于某些名字空间中。 但是名字空间资源本身并不在名字空间中。而且底层资源,例如节点和持久化卷不属于任何名字空间。可以查看相关信息:

# 位于名字空间中的资源
kubectl api-resources --namespaced=true

# 不在名字空间中的资源
kubectl api-resources --namespaced=false

五. 标签和选择算符

标签(Labels) 是附加到 Kubernetes 对象(比如 Pods)上的键值对,旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。标签可以用于组织和选择对象的子集,还可以随时添加和修改。 每个对象都可以定义一组键/值标签且每个键对于给定对象必须是唯一的。

实例:

"metadata": {
  "labels": {
    "key1" : "value1",
    "key2" : "value2"
  }
}

1.标签的目的

标签使用户能够以松散耦合的方式将其结构映射到系统对象,而无需客户端存储。服务部署和批处理流水线通常是多维实体(例如,多个分区或部署、多个发行序列、多个层,每层多个微服务)。请记住,对于给定对象标签的键必须是唯一的。 

示例标签:

  • "release" : "stable""release" : "canary"
  • "environment" : "dev""environment" : "qa""environment" : "production"
  • "tier" : "frontend""tier" : "backend""tier" : "cache"
  • "partition" : "customerA""partition" : "customerB"
  • "track" : "daily""track" : "weekly"

2. 语法和字符集

在k8s中标签以键值对出现。有效的标签键有两个段:可选的前缀和名称,用斜杠(/)分隔。 名称段是必需的,必须小于等于 63 个字符,以字母数字字符([a-z0-9A-Z])开头和结尾, 带有破折号(-),下划线(_),点( .)和之间的字母数字。 前缀是可选的。如果指定,前缀必须是 DNS 子域:由点(.)分隔的一系列 DNS 标签,总共不超过 253 个字符, 后跟斜杠(/)。如果省略前缀,假定标签键对用户是私有的。 向最终用户对象添加标签的自动系统组件(例如 kube-schedulerkube-controller-manager、 kube-apiserverkubectl 或其他第三方自动化工具)必须指定前缀。另外,kubernetes.io/ 前缀是为 Kubernetes 核心组件保留的。

强调:有效标签值必须为 63 个字符或更少,并且必须为空或以字母数字字符([a-z0-9A-Z])开头和结尾, 中间可以包含破折号(-)、下划线(_)、点(.)和字母或数字。

3. 标签选择算符

与名称和UID不同,标签部署唯一性的,一般情况下对象有许多相同的标签,通过标签选择算符,客户端/用户选择一组对象。标签选择算符是 Kubernetes 中的核心分组原语。标签选择算符可以由逗号分隔的多个 需求组成,在多个需求的情况下,必须满足所有要求,因此逗号分隔符充当逻辑 &&)运算符。对于某些 API 类别(例如 ReplicaSet)而言,两个实例的标签选择算符不得在命名空间内重叠, 否则它们的控制器将互相冲突,无法确定应该存在的副本个数。API 目前支持两种类型的选择算符:基于等值的和基于集合的。需要注意的是对于基于等值的和基于集合的条件而言,不存在逻辑或(||)操作符。

基于等值的需求

基于等值或者基于不等值的需求允许按标签键和值进行过滤,匹配对象必须满足所有指定的标签约束。运算符包括=== 和 != 三种。 前两个表示 相等(并且只是同义词),而后者表示 不相等。例如:

environment = production
tier != frontend

前者选择所有资源,其键名等于 environment,值等于 production。 后者选择所有资源,其键名等于 tier,值不同于 frontend,所有资源都没有带有 tier 键的标签。 可以使用逗号运算符来过滤 production 环境中的非 frontend 层资源:

environment=production,tier!=frontend

基于等值的标签要求Pod 要指定节点选择标,例如下面的示例 Pod 选择带有标签 "accelerator=nvidia-tesla-p100"。

apiVersion: v1
kind: Pod
metadata:
  name: cuda-test
spec:
  containers:
    - name: cuda-test
      image: "k8s.gcr.io/cuda-vector-add:v0.1"
      resources:
        limits:
          nvidia.com/gpu: 1
  nodeSelector:
    accelerator: nvidia-tesla-p100

基于等组合的需求

基于等组合的需求的标签需求允许一组值来过滤键。支持三种操作符:innotin 和 exists (只可以用在键标识符上)。例如

environment in (production, qa)
tier notin (frontend, backend)
partition
!partition
  • 第一个示例选择了所有键等于 environment 并且值等于 production 或者 qa 的资源。
  • 第二个示例选择了所有键等于 tier 并且值不等于 frontend 或者 backend 的资源,以及所有没有 tier 键标签的资源。
  • 第三个示例选择了所有包含了有 partition 标签的资源;没有校验它的值。
  • 第四个示例选择了所有没有 partition 标签的资源;没有校验它的值。 类似地,逗号分隔符充当  运算符。因此,使用 partition 键(无论为何值)和 environment 不同于 qa 来过滤资源可以使用 partition, environment notin(qa) 来实现

基于等组合的标签选择算符是相等标签选择算符的一般形式,因为 environment=production 等同于 environment in(production)!= 和 notin 也是类似的。基于集合 可以与基于 相等 的值混合使用。例如:partition in (customerA, customerB),environment!=qa

4. API

LIST 和 WATCH 过滤

LIST and WATCH 操作可以使用查询参数指定标签选择算符过滤一组对象,下面显示的是它们出现在 URL 查询字符串中:

  • 基于等值 的需求: ?labelSelector=environment%3Dproduction,tier%3Dfrontend
  • 基于集合 的需求: ?labelSelector=environment+in+%28production%2Cqa%29%2Ctier+in+%28frontend%29

两种标签选择算符都可以通过 REST 客户端用于 list 或者 watch 资源。 例如,使用 kubectl 定位 apiserver

#基于等值
kubectl get pods -l environment=production,tier=frontend

#基于集合
kubectl get pods -l 'environment in (production),tier in (frontend)'

#exists 运算符限制不匹配:
kubectl get pods -l 'environment,environment notin (frontend)'

在 API 对象中设置引用

在 Kubernetes 对象,例如services和replicationcontrollers也使用了标签选择算符去指定了其他资源的集合。

比如。一个 Service 指向的一组 Pods 是由标签选择算符定义的,这个选择算符等价于 component=redis 或 component in (redis) 。

支持基于集合需求的资源

selector:
    component: redis

支持基于集合需求的资源

在Job、 Deployment、 Replica Set 和 DaemonSet等也支持基于集合的需求

selector:
  matchLabels:
    component: redis
  matchExpressions:
    - {key: tier, operator: In, values: [cache]}
    - {key: environment, operator: NotIn, values: [dev]}

matchLabels 是由 {key,value} 对组成的映射。 matchLabels 映射中的单个 {key,value } 等同于 matchExpressions 的元素, 其 key 字段为 "key",operator 为 "In",而 values 数组仅包含 "value"。 matchExpressions 是 Pod 选择算符需求的列表。 有效的运算符包括 InNotInExists 和 DoesNotExist。 在 In 和 NotIn 的情况下,设置的值必须是非空的。 来自 matchLabels 和 matchExpressions 的所有要求都按逻辑与的关系组合到一起 -- 它们必须都满足才能匹配。

选择节点集

通过标签进行选择的一个用例是确定节点集,方便 Pod 调度。

 

六. 注解

Kubernetes 注解为对象附加任意的非标识的元数据。客户端程序(例如工具和库)能够获取这些元数据信息。

1. 为对象附加元数据

使用标签或注解将元数据附加到 Kubernetes 对象, 标签可以用来选择对象和查找满足某些条件的对象集合。 相反,注解不用于标识和选择对象。 注解中的元数据,可以很小,也可以很大,可以是结构化的,也可以是非结构化的,能够包含标签不允许的字符。注解和标签一样,是键/值对:

"metadata": {
  "annotations": {
    "key1" : "value1",
    "key2" : "value2"
  }
}

以下说明哪些信息可以使用注解来记录:

  • 由声明性配置所管理的字段。 将这些字段附加为注解,能够将它们与客户端或服务端设置的默认值、 自动生成的字段以及通过自动调整大小或自动伸缩系统设置的字段区分开来。
  • 构建、发布或镜像信息(如时间戳、发布 ID、Git 分支、PR 数量、镜像哈希、仓库地址)。
  • 指向日志记录、监控、分析或审计仓库的指针。
  • 可用于调试目的的客户端库或工具信息:例如,名称、版本和构建信息。

  • 用户或者工具/系统的来源信息,例如来自其他生态系统组件的相关对象的 URL。

  • 轻量级上线工具的元数据信息:例如,配置或检查点。

  • 负责人员的电话或呼机号码,或指定在何处可以找到该信息的目录条目,如团队网站。

  • 从用户到最终运行的指令,以修改行为或使用非标准功能

2. 语法和字符集

注解(Annotations) 存储的形式是键/值对。有效的注解键分为两部分: 可选的前缀和名称,以斜杠(/)分隔。 名称段是必需项,并且必须在63个字符以内,以字母数字字符([a-z0-9A-Z])开头和结尾, 并允许使用破折号(-),下划线(_),点(.)和字母数字。 前缀是可选的。如果指定,则前缀必须是DNS子域:一系列由点(.)分隔的DNS标签, 总计不超过253个字符,后跟斜杠(/)。 如果省略前缀,则假定注解键对用户是私有的。 由系统组件添加的注解 (例如,kube-schedulerkube-controller-managerkube-apiserverkubectl 或其他第三方组件),必须为终端用户添加注解前缀。kubernetes.io/ 和 k8s.io/ 前缀是为Kubernetes核心组件保留的。

下例子中,注解中包含 imageregistry: https://hub.docker.com/

apiVersion: v1
kind: Pod
metadata:
  name: annotations-demo
  annotations:
    imageregistry: "https://hub.docker.com/"
spec:
  containers:
  - name: nginx
    image: nginx:1.7.9
    ports:
    - containerPort: 80

七. 字段选择器

字段选择器(Field selectors)允许你根据一个或多个资源字段的值筛选 Kubernetes 资源。下为字段选择器查询的例子:

  • metadata.name=my-service
  • metadata.namespace!=default
  • status.phase=Pending

 kubectl 命令将筛选出status.phase字段值为 Running 的所有 Pod实例:

kubectl get pods --field-selector status.phase=Running


#字段选择器本质上是资源过滤器(Filters)。默认情况下,字段选择器/过滤器是未被应用的, 这意味着指定类型的所有资源都会被筛选出来。 这使得以下的两个 kubectl 查询是等价的:

kubectl get pods
kubectl get pods --field-selector ""

1.支持的字段

不同的 Kubernetes 资源类型支持不同的字段选择器。 所有资源类型都支持 metadata.name 和 metadata.namespace 字段。 使用不被支持的字段选择器会产生错误。例如:

kubectl get ingress --field-selector foo.bar=baz

#结果

Error from server (BadRequest): Unable to find "ingresses" that match label selector "", field selector "foo.bar=baz": "foo.bar" is not a known field selector: only "metadata.name", "metadata.namespace"

2. 支持的操作符

字段选择器中使用 ===和 != (= 和 == 的意义是相同的)操作符。 例如,下面这个 kubectl 命令将筛选所有不属于 default 命名空间的 Kubernetes 服务:

kubectl get services  --all-namespaces --field-selector metadata.namespace!=default

3.链式选择器

同标签和其他选择器一样, 字段选择器可以通过使用逗号分隔的列表组成一个选择链。 下面这个 kubectl 命令将筛选 status.phase 字段不等于 Running 同时 spec.restartPolicy 字段等于 Always 的所有 Pod:

kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always

4. 多种资源类型

下面这个 kubectl 命令将筛选出所有不在 default 命名空间中的 StatefulSet 和 Service:

kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace!=default

八. 推荐使用的标签

除了 kubectl 和 dashboard 之外,可以使用其他工具来可视化和管理 Kubernetes 对象。,一组通用的标签可以让多个工具之间相互操作,用所有工具都能理解的通用方式描述对象,另外推荐的标签还以一种可以查询的方式描述了应用程序。共享标签和注解都使用同一个前缀:app.kubernetes.io。没有前缀的标签是用户私有的。共享前缀可以确保共享标签不会干扰用户自定义的标签。

1. 标签

推荐使用标签列表,可用于每个资源对象

描述示例类型
app.kubernetes.io/name应用程序的名称mysql字符串
app.kubernetes.io/instance用于唯一确定应用实例的名称mysql-abcxzy字符串
app.kubernetes.io/version应用程序的当前版本(例如,语义版本,修订版哈希等)5.7.21字符串
app.kubernetes.io/component架构中的组件database字符串
app.kubernetes.io/part-of此级别的更高级别应用程序的名称wordpress字符串
app.kubernetes.io/managed-by用于管理应用程序的工具helm字符串

实例的的 StatefulSet 对象说明这些标签的实际使用情况:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app.kubernetes.io/name: mysql
    app.kubernetes.io/instance: mysql-abcxzy
    app.kubernetes.io/version: "5.7.21"
    app.kubernetes.io/component: database
    app.kubernetes.io/part-of: wordpress
    app.kubernetes.io/managed-by: helm

2. 应用和应用实例

应用可以在 Kubernetes 集群中安装一次或多次。在某些情况下,可以安装在同一命名空间中。应用的名称和实例的名称是分别记录的。例如,某 WordPress 实例的 app.kubernetes.io/name 为 wordpress,而其实例名称表现为 app.kubernetes.io/instance 的属性值 wordpress-abcxzy。这使应用程序和应用程序的实例成为可能是可识别的且每个实例都必须具有唯一的名称。

3.示例

为了说明使用这些标签的不同方式,我写一些具体的示例

简单的无状态服务

考虑使用 Deployment 和 Service 对象部署的简单无状态服务的情况。以下两个代码段表示如何以最简单的形式使用标签。

#Deployment 用于监督运行应用本身的 pods
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: myservice
    app.kubernetes.io/instance: myservice-abcxzy
...


#Service 用于暴露应用
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: myservice
    app.kubernetes.io/instance: myservice-abcxzy
...

有数据库的 Web 应用程序

稍微复杂的应用:使用 Helm 安装的 Web 应用(WordPress),其中 使用了数据库(MySQL)。以下代码片段说明用于部署此应用程序的对象的开始。

#Deployment 的开头用于 WordPress:
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: wordpress
    app.kubernetes.io/instance: wordpress-abcxzy
    app.kubernetes.io/version: "4.9.4"
    app.kubernetes.io/managed-by: helm
    app.kubernetes.io/component: server
    app.kubernetes.io/part-of: wordpress
...


#Service 用于暴露 WordPress
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: wordpress
    app.kubernetes.io/instance: wordpress-abcxzy
    app.kubernetes.io/version: "4.9.4"
    app.kubernetes.io/managed-by: helm
    app.kubernetes.io/component: server
    app.kubernetes.io/part-of: wordpress
...

#MySQL 作为 StatefulSet 暴露,包含它和它所属的较大应用程序的元数据
apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app.kubernetes.io/name: mysql
    app.kubernetes.io/instance: mysql-abcxzy
    app.kubernetes.io/version: "5.7.21"
    app.kubernetes.io/managed-by: helm
    app.kubernetes.io/component: database
    app.kubernetes.io/part-of: wordpress
...

#Service 用于将 MySQL 作为 WordPress 的一部分暴露:
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: mysql
    app.kubernetes.io/instance: mysql-abcxzy
    app.kubernetes.io/version: "5.7.21"
    app.kubernetes.io/managed-by: helm
    app.kubernetes.io/component: database
    app.kubernetes.io/part-of: wordpress
...

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐