Kubernetes 对象

Table of Contents

1 命名空间

同一个物理机群支持划分出多个虚拟集群,这些虚拟集群被称为命名空间(namespace)。

1.1 用途

  • 命名空间用于很多跨多个团队或者项目的用户场景。几个或者几十个用户的集群,不需要考虑命名空间。
  • 资源名称在同一个命名空间中是唯一的(跨空间允许相同),命名空间不支持嵌套,同一个资源只能属于一个空间。
  • 命名空间是多个用户之间划分集群资源的一种方法。
  • 轻微不同的资源,不需要使用命名空间来区分,比如同一个软件的不同版本,可通过 Label 来区分。

1.2 使用

kubectl get namespaces

Kubernetes 会创建三个初始的空间:

  • default 未指定其它命名空间的资源使用的默认空间
  • kube-system 系统创建的对象所使用的命名空间
  • kube-public 自动创建,所有用户都可使用,为集群所用

请求指定空间的资源,可通过 -namespace 参数筛选。

1.3 命名空间和 DNS

当创建一个 Service 时,Kubernetes 会创建一个对应的 DNS 条目,形式为: <service-name>.<namespace-name>.svc.cluster.local 。 如果容器使用 <service-name> 将被解析到本地命名空间的服务。如果希望跨命名空间访问,需要使用完全限定域名(FQDN)。

1.4 并非所有对象都在命名空间中

在查询资源时,可通过指定 -namespace=true/false 来查看哪些资源不在命名空间中。

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

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

2 标签和选择器

标签 是附加到 Kubernetes 对象(比如 Pods)上的键值对。

  • 标签的含义由用户定义。
  • 可以用来组织和选择对象的子集。
  • 标签可以随时添加和修改。
  • 每个对象都可以定义一组键/值标签,键不可重复。
"metadata": {
  "labels": {
    "key1" : "value1",
    "key2" : "value2"
  }
}

标签会被设置成索引,以提高查询效率和监控。如果是非标识性的,尤其是大型的结构化数据应该使用注解来记录,而不是标签。

2.1 动机

标签使用户能够以松散耦合的方式将他们自己的组织结构映射到系统对象,而无需客户端存储这些映射。

其实就是一个轻量级的标识,用于多纬度的管理(查询),具体含义由用户约定。

2.2 语法和字符集

键值对。

  • 键,可选的前缀和名称,用斜杠( / )分隔,。
    • 名称是必须的,以字母数字字符 [a-z0-9A-Z] 开头和结尾,中间包含 - _ .[a-z0-9A-Z]
    • 前缀是可选的,如果指定必须是 DNS 子域:点( . )分隔的一系列 DNS 标签,总共不超过 253 个字符,后跟斜杠( /
  • 值,小于 64 字符, [a-z0-9A-Z] 开头和结尾,中间包含 - _ .[a-z0-9A-Z]

如果省略前缀,则假定是对用户是私有的。自动系统组件必须指定前缀( kube-schedulerkube-controller-manager 等)。 kubernetes.io/ 前缀是为 Kubernetes 核心组件保留的。

2.3 标签选择器

通过标签选择器,用户可以识别一组对象。API 目前支持两种类型的选择器:

  1. 基于相等性的
  2. 基于集合的

标签选择器可以有逗号分隔的多个 需求 组成。在多个需求的情况下,必须满足所有的要求,因为逗号分隔符充当的是逻辑 运算符。

基于相等性的需求

一种使用场景是 Pods 要指定节点选择标准。

基于集合的需求

2.4 API

3 字段选择器

字段选择器允许用户根据一个或者多个资源字段值筛选资源。比如 metadata.name=my-servicestatus.phase=Pending

kubectl 命令通过 --field-selector 筛选资源,比如:

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

3.1 支持的字段

不同的资源类型(deployment,pod 等)支持不同的字段选择器,所有的资源都支持 metadata.namemetadata.namespace

3.2 支持的运算符

  • 相等: === 两者意义相同
  • 不相等: !=

3.3 链式选择器

通过逗号分隔组成一个选择链,逗号表示

3.4 多种资源类型

多种资源类型中逗号分隔,可以 同时 筛选。比如:

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

4 推荐使用的标签

https://kubernetes.io/zh/docs/concepts/overview/working-with-objects/common-labels/

范例:

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

4.1 一个简单的无状态服务

Deployment

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

4.2 有状态服务

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

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

5 理解 Kubernetes 对象

Kubernetes 使用 对象 来表示整个集群的状态。它们描述了:

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

没创建一个对象,本质上是告知 Kubernetes 系统,所需要的集群工作负载看起来是什么样的,这就是集群的 期望状态(Desired State)

理解上面这一点很重要。

Kubernetes 对象的操作(CRUD) 都需要使用 Kubernetes API。kubectl 其实也是将 API 的一层封装成了 CLI 工具;同样,用户可以通过客户端库调用 API。

5.1 对象规约(Spec)和状态(Status)

每个 Kubernetes 对象包含两个嵌套的字段,它们负责管理对象的配置:一个是对象 Spec;一个是 Status;

  • Spec 是必须的,用来描述对象的 期望状态(Desired State)
  • Status 是可选的,它描述对象的 实际状态(Actual State) ,它由 Kubernetes 系统提供和更新

*在任何时刻,Kubernetes 都一直努力的实现 Spec 和 Status 相匹配。

5.2 描述 Kubernetes 对象

创建 Kubernetes 对象时,必须提供对象的 Spec,描述对象的期望状态,以及关于对象的一些基本信息(名称,空间等)。 API 请求必须在 body 中包含 JSON 信息。kubectl 使用 yaml 格式,发起请求时,将这些信息转换成 JSON。比如:

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

5.3 必须字段

创建 Kubernetes 对象中对应的 .yaml 文件,需要配置如下字段:

  • apiVersion 创建该对象所使用的 Kubernetes API 版本
  • kind 想要创建的对象类型
  • metadata 帮助识别对象唯一性的数据,包括 name 、UID 和可选的 namespace
  • spec 不同的 Kubernetes 对象 spec 格式不同

Date: 2020-02-05 12:25:24

Author: JerryZhang