博客:cbb777.fun
全平台账号: 安妮的心动录
github: https://github.com/anneheartrecord
下文中我说的可能对,也可能不对,鉴于笔者程度无限,请君自辨。有问题欢送大家找我探讨
K8S 对象
什么是 K8S 对象
在 k8s 中,对象是长久化的实体,k8s 应用这些实体去示意整个集群的状态,它们形容了以下信息
- 哪些容器化利用正在运行
- 能够被利用应用的资源
- 对于利用运行时行为的策略,比方重启策略、降级策略以及容错策略
k8s 对象是一种 ” 动向表白(Record of Intent)”,一旦创立该对象,K8S 零碎将一直工作以确保该对象存在。最终零碎应该达到 K8S 所谓的冀望状态
咱们操作 K8S 对象须要用到 K8S 的 API,能够间接应用 kubectl
命令行,也能够在程序中应用客户端库,间接调用 K8S API
对象规约(spec)与状态(status)
简直每个 Kubernetes 对象都蕴含两个嵌套的字段,它们负责管理对象的配置,别离是 spec
与status
对于具备 spec 的对象,你必须在创建对象时设置其内容,形容心愿对象所具备的特色:冀望状态(desired state)
status 形容了对象的以后状态(current state),它是由 k8s 零碎和组件设置并更新的。
在任何时刻,管制立体都在治理对象的理论状态,以使其达成冀望状态
形容 K8S 对象
创立 K8S 对象的时候必须提供对象的 spec 用来形容对象的冀望状态,以及对象的 一些根本信息(name kind),过后用 API 创立独享的时候,API 在申请主体中应该蕴含 JSON 格局的数据,大部分状况下咱们提供的是 .yaml
文件来为 kubectl
提供这些信息,当 kubectl
发动 API 申请的时候,这些信息会被转换成 JSON 格局
上面是一个.yaml 的示例
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
除了通过 .yaml
这种申明式 API 的形式创立 Deployment,也能够通过 kubectl
命令行的形式,通过命令将 .yaml
文件作为参数进行创立,上面是一个栗子
kubectl apply -f https://k8s.io/examples/application/deployment.yaml // 利用某 yaml 文件
deployment.apps/nginx-deployment created // output
必须字段
在创立 K8S 对象中应用的 .yaml
文件里,须要配置的字段如下
apiVersion
创建对象应用的 K8S API 的版本kind
想要创立的对象类型metadata
帮忙惟一标识对象的一些数据 比方 name uid 和可选的 namespacespec
所冀望的该对象的状态
K8S 对象治理
kubectl
命令行工具反对多种不同的形式来创立和治理 k8s 对象,须要留神的是应该只应用一种技术来治理 k8s 对象,混合和匹配技术作用在同一对象上将会导致未被定义的行为
- 指令式命令 作用于沉闷对象 反对多个写者 难度低
- 指令式对象配置 作用于单个文件 反对一个写者 难度中等
- 申明式对象配置 作用于文件目录 反对多个写者 难度高
指令式命令
应用指令式命令时,用户能够在集群中的流动对象上进行操作,用户将操作传递给 kubectl
命令作为参数或者标记
举荐在开始的时候或者在集群中运行一次性工作应用这种形式,因为它间接作用在流动对象上,所以它不提供以前配置的历史记录
上面是一个创立 deployment 对象来运行 nginx 的实例
kubectl create deployment nginx --image nginx
指令式对象配置
kubectl
命令制订操作,可选标记和至多一个文件名,文件内须要蕴含 YAML
或者 JSON
格局的对象的残缺定义
上面是一些栗子
kubectl create -f nginx.yaml // 创立配置文件中定义的对象
kubectl delete -f nginx.yaml -f redis.yaml // 删除两个配置文件中定义的对象
kubectl replace -f nginx.yaml // 笼罩配置文件中定义的对象
申明式对象配置
应用申明式对象配置时,用户对本地存储的对象配置文件进行操作,然而用户未定义要对文件执行的操作,kubectl
会自动检测每个文件的创立、更新和删除操作,这使得配置能够在目录上工作,依据目录中配置文件对不同的对象执行不同的操作
kubectl diff -f configs/ // 查看 configs 目录下所有对象配置文件要进行的更改
kubectl apply -f configs/ // 将 configs 目录下要进行的更改利用
对象名称与 ID
集群中的每一个对象都有一个名称来标识其在同类资源中的唯一性
每个 K8S 对象也有一个 UID 来标识在整个集群中的唯一性
比方同一个 namespace
下只能有一个名为 abc 的 pod,然而能够命名一个 pod 和一个 deployment 同为 abc
名称
是客户端提供的字符串,援用资源 URL 中的对象,如/api/v1/pods/xxx
某一时刻,只能有一个给定类型的对象具备给定的名称。然而如果删除该对象就能够创立同名的新对象
名称在同一资源的所有 API 版本中必须是惟一的,这些 API 资源通过各自的 API 组、资源类型、命名空间和名称来辨别,也就是说 API 版本在上下文中不相干的
资源命名束缚有 DNS 子域名
、RFC 1123 标签名
、RFC 1035 标签名
、 门路分段名称
这四种命名束缚
UID
uid 是系统生成的字符串,惟一标识对象,在 K8S 集群中每个生命周期中创立的每个对象都有一个不同的 UID
标签与抉择算法
标签(Labels)
是附加到 K8S 对象(比方 Pod)上的键值对,旨在指定对用户有意义并且相干的对象的标识属性,但不间接对外围零碎有语义含意。标签能够用于组织和选择对象的子集,能够在创立时附加到对象,随后能够轻易增加和批改,每个对象都能够定义一组键值标签,每个键对于给定的对象必须是惟一的
"metadata": {
"labels": {
"key1" : "value1",
"key2" : "value2"
}
}
标签可能容许用户以松耦合的形式将他们本人的组织构造映射到零碎对象,而无需客户端存储这些映射
常见标签
- “release” : “stable”, “release” : “canary”
- “environment” : “dev”, “environment” : “qa”, “environment” : “production”
- “tier” : “frontend”, “tier” : “backend”, “tier” : “cache”
- “partition” : “customerA”, “partition” : “customerB”
- “track” : “daily”, “track” : “weekly”
上面是一个 lables 带有 enviroment 和 app 两个标签的 pod
apiVersion: v1
kind: Pod
metadata:
name: label-demo
labels:
environment: production
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
标签抉择算符
与名称和 UID 不同的是,标签不反对唯一性,通常咱们心愿许多对象携带雷同的标签
通过标签抉择算符,客户端 / 用户能够辨认一组对象
API 目前反对两种类型的抉择算符:等值和汇合
等值反对三个运算符 别离是 =
==
!=
前两者示意相等,含意雷同,后者示意不相等
例如
environment = production //environment label 等于 xx
tier != fronted // tier label != xx
//pod 抉择 accelerator = nvidia
apiVersion: v1
kind: Pod
metadata:
name: cuda-test
spec:
containers:
- name: cuda-test
image: "registry.k8s.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1
nodeSelector:
accelerator: nvidia-tesla-p100
基于汇合的标签容许通过一组值来过滤间 反对三种操作符 in notin 和 exists
environment in (a,b) //env = a 或 b
tirer notin (a,b) // tire != a & tirer != b
partition // 蕴含了 partition 标签
!partition // 没蕴含 partition 标签
API
kubectl get pods -l environment=production,tier=frontend
kubectl get pods -l 'environment in (production),tier in (frontend)'
命名空间
Namespace
提供了一种机制,将同一集群中的资源划分为互相隔离的组,同一 Namespace
内的资源名称要惟一,每个 K8s 资源只能在一个 Namespace
中,这其实是在多个用户之间划分集群资源的一种办法
初始命名空间
k8s 启动的时候会创立四个初始化命名空间
default
k8s 蕴含这个命名空间,以便于你无需创立新的命名空间就能够应用新集群kube-node-lease
蕴含用于各个节点关联的Lease
租约对象,节点租约容许kubelet
发送心跳,由此控制面板可能检测到结点故障kube-public
所有的客户端(包含未经身份验证的客户端)都能够读取该命名空间,该命名空间次要预留为集群应用,以便某些资源能够在整个集群中可见可读kube-system
用于 k8s 零碎创立的对象
kubectl get namespace // 列出集群中现存的 namespace
kubectl run nginx --image=nginx --namespace=<namespacename>
当创立一个服务的时候,k8s 会创立一个相应的 DNS 条目
该条目标模式是< 服务名称 >.< 名字空间名称 >.svc.cluster.local
,这意味着如果容器只应用服务名称,就会被解析到本地命名空间的服务
大多数对象都存在 namespace
中,比方 pod、service 等,然而 namespace
的资源自身并不在 namespace
中,而且底层资源,比方 node 和长久化卷,不属于任何命名空间
注解
能够通过注解给对象增加任意的非标识的元数据,客户端能够获取这些元数据信息,注解只是增加一些元数据信息,不用来示意和选择对象,相似于编程中的正文,不过这是对于 K8S 对象的正文
"metadata": {
"annotations": {
"key1" : "value1",
"key2" : "value2"
}
}
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
通常咱们能够用注解来记录以下这些信息
- 由申明性配置所治理的字段。将这些字段附加为注解,可能将它们与客户端或服务端设置的默认值、主动生成的字段以及通过主动调整大小或主动伸缩零碎设置的字段辨别开来。
- 构建、公布或镜像信息(如工夫戳、公布 ID、Git 分支、PR 数量、镜像哈希、仓库地址)。
- 指向日志记录、监控、剖析或审计仓库的指针。
- 可用于调试目标的客户端库或工具信息:例如名称、版本和构建信息。
- 用户或者工具 / 零碎的起源信息,例如来自其余生态系统组件的相干对象的 URL。
- 轻量级上线工具的元数据信息:例如配置或检查点。
- 负责人员的电话或呼机号码,或指定在何处能够找到该信息的目录条目,如团队网站。
- 从用户到最终运行的指令,以批改行为或应用非标准性能。
字段选择器
字段选择器 Field Selectors
容许你依据一个或者多个资源字段的值筛选 K8S 对象
kubectl get pods --field-selector status.phase=Running // 筛进去 status.phase 字段值为 runnning 的所有 Pod
不同的 k8s 资源类型反对不同的字段选择器,所有资源类型都反对 metadata.name
和metadata.namespace
字段,应用不被反对的字段选择器会产生谬误
终结器
终结器(Finalizer)是带有命名空间的键,通知 k8s 等到特定的条件被满足后,再齐全删除被标记为删除的资源,Finalizer
揭示控制器清理被删除的对象领有的资源
当你通知 K8S 删除一个指定了 Finalizer
的对象时,K8S API 通过填充 .metadata.deletionTimestamp
来标记要删除的对象,并返回 202 状态码使其进入只读状态,此时管制立体或者其余组件会采取 Finalizer
所定义的口头,而指标对象依然处于终止中(Terminating)的状态,这些行为实现后,控制器会删除指标对象相干的 Finalizer
。当metadata.finalizers
字段为空时,kubernetes 认为删除已实现并删除对象
工作原理
当应用清单文件创建资源的时候,能够在 metadata.finalizers
中指定 Finalizers。当视图删除该资源的时候,解决删除申请的 API 服务器会留神到 finalizers
字段中的值,并进行以下操作
- 批改对象 将开始执行删除的工夫增加到
metadata.deletionTimestamp
字段 - 禁止对象被删除,直到其
metadata.finalizers
字段为空 - 返回 202 状态码
属主与从属
在 K8S 中,一些对象是其余对象的Owner
。例如 ReplicaSet 是一组 Pod 的属主,具备属主的对象是属主的从属(Dependent)
从属对象中有一个 metadata.ownerReferences
字段,用于援用其属主对象,一个无效的属主援用,蕴含与属主对象同在一个命名空间下的对象名称和一个 UID,K8S 主动为一些对象的从属资源设置属主援用的值,这些对象蕴含了 ReplicaSet
DaemonSet
Deployment
Job
CronJob
ReplicationController
等
举荐应用的标签
除了 kubectl
和dashboard
之外,还能够应用其余工具来可视化和治理 K8S 对象,一组通用的标签能够让多个工具之间互相操作,用所有工具都能了解的通用形式形容对象
元数据围绕利用的概念进行组织,K8S 不是平台即服服务,应用程序是非正式的,并且应用元数据进行形容,应用程序蕴含的定义应该是送伞的
共享标签和注解都是用同一个前缀:app.kubernetes.io
,没有前缀的标签是用户公有的,共享前缀能够确保共享标签不会烦扰用户自定义的标签
键 | 形容 | 示例 | 类型 |
---|---|---|---|
app.kubernetes.io/name | 应用程序的名称 | mysql | 字符串 |
app.kubernetes.io/instance | 用于惟一确定利用实例的名称 | mysql-abcxzy | 字符串 |
app.kubernetes.io/version | 应用程序的以后版本(例如语义版本 1.0 | ||
、修订版哈希等) | 5.7.21 | 字符串 | |
app.kubernetes.io/component | 架构中的组件 | database | 字符串 |
app.kubernetes.io/part-of | 此级别的更高级别应用程序的名称 | wordpress | 字符串 |
app.kubernetes.io/managed-by | 用于管理应用程序的工具 | helm | 字符串 |