应用编排与管理

一. 理解 kubernetes 中的对象

在 Kubernetes 系统中,Kubernetes 对象是持久化的实体。Kubernetes 使用这些实体去表示整个集群的状态。具体来说,它们描述了如下信息:

  • 哪些容器化应用程序正在运行(以及在哪些节点上运行);
  • 这些应用程序可用的资源;
  • 有关这些应用程序行为的策略,如重启策略、升级策略和容错策略

一个Kubernetes对象是一个“意向型记录”,一旦你创建了这个对象,Kubernetes系统就会不断地工作以确保这个对象存在。通过创建一个对象,您可以有效地告诉Kubernetes系统您希望集群的工作负载是什么样的;这就是集群的期望状态

要使用Kubernetes对象,无论是创建、修改还是删除它们,都需要使用Kubernetes API。例如,当您使用kubectl命令行界面时,CLI会为您进行必要的Kubernetes API调用。您也可以在自己的程序中使用一个Client Libraries来直接使用Kubernetes API。

1.1 对象的spec和status

几乎每个Kubernetes对象都包含两个控制对象配置的嵌套对象字段:object spec和object status。

  • spec 必须提供,它描述了对象的期望状态–希望对象所具有的特征。
  • status 描述了对象的实际状态,它是由Kubernetes系统提供和更新。

在任何时刻,Kubernetes控制平面一直处于活跃状态,管理着对象的实际状态以与我们所期望的状态相匹配。

例如,Kubernetes Deployment 对象能够表示运行在集群中的应用。当创建 Deployment 时,可能需要设置 Deployment 的 spec,以指定该应用需要有 3 个副本在运行。Kubernetes 系统读取 Deployment spec,启动我们所期望的该应用的 3 个实例,更新状态以与 spec 相匹配。如果那些实例中有失败的(一种状态变更),Kubernetes 系统通过修正来响应 spec 和 status 之间的不一致,这种情况,启动一个新的实例来替换。

1.2 描述一个 Kubernetes 对象

当创建 Kubernetes 对象时,必须提供对象的 spec,用来描述该对象的期望状态,以及关于对象的一些基本信息(例如,名称)。当使用 Kubernetes API 创建对象时(或者直接创建,或者基于kubectl),API 请求必须在请求体中包含 JSON 格式的信息。更常用的是,需要在 .yaml 文件中为 kubectl 提供这些信息。 kubectl 在执行 API 请求时,将这些信息转换成 JSON 格式。

下面是一个 .yaml 示例文件,展示了 Kubernetes Deployment 的必需字段和对象 spec:

## application/deployment.yaml 

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # tells deployment to run 2 pods matching the template
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

有了 .yaml 文件,就可以使用 kubectl 命令进行创建了

kubectl apply -f https://k8s.io/examples/application/deployment.yaml --record

输出以下结果:

deployment.apps/nginx-deployment created

1.3 必须字段

您要创建的Kubernetes对象的 .yaml 文件中,您需要为以下字段设置值:

  • apiVersion :正在使用哪个版本的Kubernetes API创建该对象;
  • kind :要创建哪种对象;
  • metadata:有助于唯一标识对象的数据,包括name字符串UID,和可选namespace;
  • spec :对对象的期望状态;

对于不同的kubernetes对象来说,spec的准确格式不一样的,以及其对象嵌套的区域字段。

可以参考官方API格式:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/

1.4 object对象

以下列举的内容都是 kubernetes 中的 Object,这些对象都可以在 yaml 文件中作为一种 API 类型来配置。

  • Pod
  • Node
  • Namespace
  • Service
  • Volume
  • PersistentVolume
  • Deployment
  • Secret
  • StatefulSet
  • DaemonSet
  • ServiceAccount
  • ReplicationController
  • ReplicaSet
  • Job
  • CronJob
  • SecurityContext
  • ResourceQuota
  • LimitRange
  • HorizontalPodAutoscaling
  • Ingress
  • ConfigMap
  • Label
  • CustomResourceDefinition
  • Role
  • ClusterRole

二. 管理kubernetes中的对象

kubectl命令行工具支持几种不同的方法来创建和管理Kubernetes对象。可以查看详细使用方法:https://kubectl.docs.kubernetes.io/

管理技术 操作对象 推荐环境 支持可写者 学习曲线
命令式命令 活跃对象 开发项目 1+ 最低
命令式对象配置 单个文件 生产项目 1个 中等
声明式对象配置 文件目录 生产项目 1+ 最高

2.1 命令式执行命令

当使用命令时,用户直接操作集群中的活动对象。用户将操作作为参数提供给kubectl命令。

这是在集群中启动或运行一次性任务的最简单方法。由于此方式直接在活动对象上操作,因此它不提供以前配置的历史记录。例如:

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

##使用不同的语法执行相同的操作:
# kubectl create deployment nginx --image nginx

与对象配置相比的优势:

  • 命令简单易学,易记;
  • 命令只需要一个步骤就可以对集群进行更改;

与对象配置相比的缺点:

  • 命令不与变更评审过程集成;
  • 命令不提供与更改相关联的审核跟踪;
  • 命令不提供源的记录;
  • 命令不提供用于创建新对象的模板;

2.2 命令式对象配置

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

例如:

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

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

##更新定义在配置文件中的对象,覆盖当前的配置
# kubectl replace -f nginx.yaml

与命令命令相比的优势:

  • 对象配置可以存储在源代码管理系统(如Git)中;
  • 对象配置可以与流程集成,例如在推送和审核跟踪之前查看更改;
  • 对象配置提供了创建新对象的模板。

与命令命令相比的缺点:

  • 对象配置需要基本了解对象架构;
  • 对象配置需要编写YAML文件的附加步骤;

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

  • 命令式对象配置行为更简单、更易于理解;
  • 从Kubernetes 1.5版开始,命令式对象配置更加成熟。

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

  • 命令式对象配置最适合于文件,而不是目录;
  • 对活动对象的更新必须反映在配置文件中,否则它们将在下一次替换期间丢失。

2.3 声明性对象配置

当使用声明性对象配置时,用户对本地存储的对象配置文件进行操作,但是用户不定义要对文件执行的操作。kubectl会自动为每个对象检测创建、更新和删除操作。这允许在目录上工作,不同的对象可能需要不同的操作。

例如:

##将处理的所有对象配置文件放入到configs目录,创建或修补这些活跃的对象。
##可以首先比较一下,以查看将要进行的更改,然后再应用
# kubectl diff -f configs/
# kubectl apply -f configs/

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

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

  • 直接对活动对象所做的更改将被保留,即使它们没有合并到配置文件中;
  • 声明性对象配置更好地支持在目录上操作和自动检测每个对象的操作类型(创建、修补、删除)。

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

  • 声明性对象配置在意外情况下很难调试和理解结果;
  • 使用差异的部分更新会创建复杂的合并和修补操作;

三. 对象的名称和ID

群集中的每个对象都有一个对于该资源类型唯一的名称。每个Kubernetes对象还具有在整个集群中唯一的UID。

例如你在相同的namespace里只能有一个名字为 myapp-1234 的Pod,但是你能有一个Pod和一个Deployment,名字都是 myapp-1234。

对于用户提供的非唯一属性,Kubernetes提供labels和annotations。

3.1 Names

一个客户端提供的字符串,在一个资源URL中来查阅一个对象,例如:/api/v1/pods/some-name

一次只能给一个类型的对象一个名字,但是,如果对象被删除,你能使用同样的名字生成一个新的对象。下面是常用的三种类型名称的资源限制:

DNS子域名称

大多数资源类型需要一个DNS子域名称:

  • 不超过253个字符;
  • 仅包含小写字母、数字字符、“-”或“.”;
  • 以字母数字字符开头;
  • 以字母数字字符结尾;

DNS Label名称

一些资源类型要求其名称遵循DNS Label标准。这意味着该名称必须:

  • 最多包含63个字符;
  • 仅包含小写字母、数字字符或“-”;
  • 以字母数字字符开头;
  • 以字母数字字符结尾;

路径段名称(Path Segment Names)

有些资源类型要求其名称能够安全地编码为路径段。换句话说,名称不能是“.”或“…”,并且名称不能包含“/”或“%”。

下面是一个名称为nginx-demo的Pod的示例清单:

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

##某些资源类型对其名称有其他限制

3.2 UIDS

Kubernetes系统生成字符串来唯一标识对象。

在Kubernetes集群的整个生命周期中创建的每个对象都有一个不同的UID。它旨在区分类似实体的历史事件。

Kubernetes uid是通用的唯一标识符(也称为uuid)。uuid标准化为ISO/IEC 9834-8和ITU-T X.667。

四. 名称空间(Namespaces)

Kubernetes支持由同一物理集群支持的多个虚拟集群。这些虚拟集群称为名称空间。

名称空间旨在用于具有分布在多个团队或项目中的许多用户的环境中。对于拥有几个到几十个用户的集群,您根本不需要创建或考虑名称空间。

名称空间提供名称的作用域。资源的名称在命名空间中必须是唯一的,但不能跨命名空间。名称空间不能相互嵌套,每个Kubernetes资源只能位于一个名称空间中。

名称空间是一种在多个用户之间划分集群资源的方法(通过资源配额)。

在Kubernetes的未来版本中,默认情况下,相同命名空间中的对象将具有相同的访问控制策略。

不必使用多个名称空间来分隔稍有不同的资源,例如同一软件的不同版本:使用标签来区分同一名称空间中的资源。

4.1 显示namespaces

##列出当前使用的集群中的namespaces
# kubectl get namespaces

##得到如下结果:
NAME          STATUS    AGE
default       Active    11d
kube-system   Active    11d
kube-public   Active    11d
  • default:如果没有其它的namespace,这个是对象的默认命名空间;
  • kube-system:与集群管理相关的为整个集群提供服务的应用一般部署在kube-system的namespace下;
  • kube-public:这个名称空间是自动创建的,所有用户(包括未经身份验证的用户)都可以读取。这个名称空间主要是为集群使用而保留的,以防某些资源在整个集群中公开可见和可读。这个名称空间的公共方面只是一个约定,而不是一个要求。
##可以查看指定namespace的汇总信息
#kubectl get namespaces <name>

##可以查看指定namespace的详细信息
# kubectl describe namespaces <name>

##类似如下输出:
Name:           default
Labels:         <none>
Annotations:    <none>
Status:         Active

No resource quota.

Resource Limits
 Type       Resource    Min Max Default
 ----               --------    --- --- ---
 Container          cpu         -   -   100m

注意

  • 这些详细信息同时显示资源配额(如果存在)和资源限制范围;
  • 资源配额跟踪命名空间中资源的聚合使用情况,并允许群集操作和定义命名空间可能使用的硬资源使用限制;
  • 限制范围定义了单个实体在命名空间中可以使用的资源量的最小/最大限制。

一个命名空间应该是以下两个阶段之一:

  • Active :这个命名空间在使用中;
  • Terminating :这个命名空间正在被删除中,不能用于新的对象;

4.2 创建和删除namespaces

先创建一个my-namespace.yaml文件

apiVersion: v1
kind: Namespace
metadata:
  name: <insert-namespace-name-here>

然后运行:

# kubectl create -f ./my-namespace.yaml

也可以直接使用命令行:

##这个namespace的名字必须是一个可用的: DNS label
# kubectl create namespace <insert-namespace-name-here>

删除一个namespace:

# kubectl delete namespaces <insert-some-namespace-name>

## 会删除这个namespace下的所有一切。删除是异步的。

4.3 使用namespace

##将对象创建在指定的namespace下,并查看
# kubectl run nginx --image=nginx --namespace=<insert-namespace-name-here>
# kubectl get pods --namespace=<insert-namespace-name-here>

4.4 namespaces和DNS

创建service时,它会创建一个相应的DNS条目。此项的形式为<service-name>.<namespace-name>.svc.cluster.local,这意味着如果容器仅使用,它将解析为名称空间本地的服务。这对于在多个名称空间(例如开发,阶段和生产)中使用相同的配置很有用。如果要跨命名空间访问,则需要使用完全限定的域名(FQDN)。

大多数Kubernetes资源(例如pod,services,replication controllers和其他资源)都位于某些命名空间中。但是,名称空间资源本身并不在名称空间中。而且低级资源(例如nodes和persistentVolumes)不在任何命名空间中。

要查看哪些Kubernetes资源在命名空间中和不在其中:

## In a namespace
# kubectl api-resources --namespaced=true

## Not in a namespace
# kubectl api-resources --namespaced=false

五. 标签(Labels)和选择器(Selectors)

标签是附加到对象(如pod)的键/值对。标签用于指定对象的标识属性,这些属性对用户有意义且相关,对于系统本身来说没有任何意义。标签可用于组织和选择对象的子集。标签可以在创建时附加到对象,然后可以随时添加和修改。每个对象都可以定义一组键/值标签。对于给定的对象,每个键必须是唯一的。

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

Kubernetes最终将对labels最终索引和反向索引用来优化查询和watch,在UI和命令行中会对它们排序。不要在label中使用大型、非标识的结构化数据,记录这样的数据应该用annotation。

5.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"

这些只是常用标签的示例,您可以根据自己的惯例开发自己的标签。请记住,对于给定的对象,标签键必须是唯一的。

5.2 语法和字符集

Label key的组成:

  • 不得超过63个字符;
  • 可以使用前缀,使用/分隔,前缀必须是DNS子域,不得超过253个字符,系统中的自动化组件创建的label必须指定前缀,kubernetes.io/ 和 k8s.io/ 前缀由kubernetes保留;
  • 起始必须是字母(大小写都可以)或数字,中间可以有连字符、下划线和点

Label value的组成:

  • 不得超过63个字符;
  • 起始必须是字母(大小写都可以)或数字,中间可以有连字符、下划线和点;
apiVersion: v1
kind: Pod
metadata:
  name: label-demo
  labels:
    environment: production  ##这是一个labels
    app: nginx               ##这个第二个labels
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

5.3 标签选择器(Label selectors)

与名称和uid不同,标签不提供唯一性。一般来说,我们希望许多对象都带有相同的标签。

通过标签选择器,客户端/用户可以识别一组对象。标签选择器是Kubernetes中的核心分组原语。

Label selector有两种类型:

  • equality-based :可以使用=、==、!=操作符,可以使用逗号分隔多个表达式;标签选择器可以由逗号分隔的多个需求组成。在多个要求的情况下,必须满足所有要求,逗号分隔符充当逻辑和(&&)运算符。
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  ##Pod选择这个标签的node
  • set-based :可以使用in、notin、exists,另外还可以没有操作符,直接写出某个label的key,表示过滤有某个key的object而不管该key的value是何值,!表示没有该label的object;
##选择key等于environment,并且value等于production或qa的所有资源
environment in (production, qa)  

##选择key是tier,且value是除了frontedn或backend外地所有资源,以及没有key是tier的label的所有资源
tier notin (frontend, backend)

##选择带有key是partition的标签的所有资源,不管value是多少
partition

##选择不带有key是partition的标签的所有资源,不管value是多少
!partition

两种类型还可以混合使用

partition in (customerA, customerB),environment!=qa

Kubectl可以使用

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)'

5.4 在API object中设置label selector

Service and ReplicationController

用标签选择器定义一个service目标的pod集。类似地,ReplicationController应该管理的pod的数量也由标签选择器定义。

这两个对象的标签选择器在json或yaml文件中定义,并且只支持equality-based的选择器:

"selector": {
    "component" : "redis",
}
##或者
selector:
    component: redis

支持set-based的需求的资源

Job, Deployment, ReplicaSet和DaemonSet这些新的对象支持set-based的标签选择器。

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

## matchLabels和matchExpressions所有的条件必须全部满足才会匹配
## operator的值可以是In, NotIn, Exists 和 DoesNotExist

六. 注释(Annotation)

Annotation,顾名思义,就是注解。Annotation可以将Kubernetes资源对象关联到任意的非标识性元数据。使用客户端(如工具和库)可以检索到这些元数据。

6.1 关联元数据到对象

Label和Annotation都可以将元数据关联到Kubernetes资源对象。Label主要用于选择对象,可以挑选出满足特定条件的对象。相比之下,annotation 不能用于标识及选择对象。annotation中的元数据可多可少,可以是结构化的或非结构化的,也可以包含label中不允许出现的字符。

annotation和label一样都是key/value键值对映射结构:

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

以下列出了一些可以记录在 annotation 中的对象信息:

  • 由声明配置层管理的字段。使用annotation关联这类字段可以用于区分以下几种配置来源:客户端或服务器设置的默认值,自动生成的字段或自动生成的 auto-scaling 和 auto-sizing 系统配置的字段。
  • 创建信息、版本信息或镜像信息。例如时间戳、版本号、git分支、PR序号、镜像哈希值以及仓库地址。
  • 记录日志、监控、分析或审计存储仓库的指针
  • 可以用于debug的客户端(库或工具)信息,例如名称、版本和创建信息。用户信息,以及工具或系统来源信息、例如来自非Kubernetes生态的相关对象的URL信息。
  • 轻量级部署工具元数据,例如配置或检查点。
  • 负责人的电话或联系方式,或能找到相关信息的目录条目信息,例如团队网站。
  • 从最终用户到实现的指令,以修改行为或使用非标准功能。

如果不使用annotation,您也可以将以上类型的信息存放在外部数据库或目录中,但这样做不利于创建用于部署、管理、内部检查的共享工具和客户端库。

## 带有注释:imageregistry: https://hub.docker.com/的Pod的配置文件
apiVersion: v1
kind: Pod
metadata:
  name: annotations-demo
  annotations:
    imageregistry: "https://hub.docker.com/"
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

七. 字段选择器(Field Selectors)

字段选择器让你通过单个或多个资源字段的值来选择kubernates资源。这是一些字段选择器查询例子:

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

下面的kubectl命令选择所有status.phase字段的值是Running的Pods

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

字段选择器是基本资源过滤器。默认情况,没有使用选择器/过滤器的话,意味着所有类型的资源都被选中。所以下列的kubectl查询是等价的。

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

7.1 支持的字段

不同类型的Kubernetes资源支持的字段选择器之同。所有类型资源都支持 metadata.namemetadata.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"

7.2 支持的操作符

你可以在字段选择器中使用 =、、!= 操作符( =和是相同的 )。 下例kubectl命令选择所有不在default名称空间的Kubernetes Services。

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

7.3 链选择器

和 label 还有其他选择器一样,字段选择器可以彼此连接成一个逗号分隔的列表。下例kubectl命令选择了所有 status.phase 不为 Running 且 spec.restartPolicy 为 Always 的 Pod。

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

7.4 多资源类型

你可以跨越多资源类型使用字段选择器。下例kubectl命令选择了所有不在default 名称空间的Statefulsets和Services。

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

八. 推荐标签(Recommended Labels)

您可以使用kubectl和仪表板dashboard更多的工具来可视化和管理Kubernetes对象。一组通用标签允许工具互操作,以所有工具都可以理解的通用方式描述对象。

除了支持工具之外,推荐标签还以可查询的方式描述应用程序。

元数据是围绕应用程序的概念组织的。Kubernetes不是一个Paas(platform as-as-a-service,PaaS),并且没有也不强制应用的格式观念。相反,应用是非正规的且通过元数据描述。

这些是推荐的标签。它们使管理应用程序变得更容易,但对于任何核心工具来说都不是必须的。

共享labels和annotations共享一个公共前缀:app.kubernetes.io。没有前缀的labels是用户私有的。共享前缀确保共享标签不会对用户自定义标签产生干扰。

8.1 标签(labels)

为了完全获得使用这些标签的好处,它们应该被用于每个资源对象上。

Key Description Example Type
app.kubernetes.io/name The name of the application mysql string
app.kubernetes.io/instance A unique name identifying the instance of an application wordpress-abcxzy string
app.kubernetes.io/version The current version of the application (e.g., a semantic version, revision hash, etc.) 5.7.21 string
app.kubernetes.io/component The component within the architecture database string
app.kubernetes.io/part-of The name of a higher level application this one is part of wordpress string
app.kubernetes.io/managed-by The tool being used to manage the operation of an application helm string

为了演示这个标签的好处,仔细考虑下面这个 StatefulSet 对象:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app.kubernetes.io/name: mysql
    app.kubernetes.io/instance: wordpress-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

8.2 应用和应用的实例(Applications And Instances Of Applications)

一个应用程序可以一次或多次安装到Kubernetes集群中,在某些情况下,可以安装在同一名称空间中。例如,在不同的网站是不同的wordpress安装位置的情况下,可以多次安装wordpress。

应用程序名称和实例名称分别记录。例如,在 WordPress 具有 app.kubernetes.io/name 的 wordpress,同时它有一个实例名,被表示为 app.kubernetes.io/instance 具有值 wordpress-abcxzy。这使得应用程序和应用程序实例是可识别的。应用程序的每个实例都必须具有唯一的名称。

8.3 案例

为了说明使用这些标签的不同方法,以下示例具有不同的复杂性。

一个简单的无状态服务(A Simple Stateless Service)

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

Deployment用于监视运行应用程序本身的pod。

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应用和一个数据库(Web Application With A Database)

稍微复杂的应用:包含数据库(MySQL)的web应用(WordPress),使用Helm安装。下面的片段展示了用来部署该应用的对象的开头。

用于WordPress的Deployment的开头。

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 用于暴露属于WordPress一部分的 MySQL:

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
...

通过MySQL的StatefulSet和Service,你可以获得MySQL和Wordpress的信息,包括更广泛的应用。