博客: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对象都蕴含两个嵌套的字段,它们负责管理对象的配置,别离是specstatus

对于具备spec的对象,你必须在创建对象时设置其内容,形容心愿对象所具备的特色:冀望状态(desired state)

status形容了对象的以后状态(current state),它是由k8s零碎和组件设置并更新的。

在任何时刻,管制立体都在治理对象的理论状态,以使其达成冀望状态

形容K8S对象

创立K8S对象的时候必须提供对象的spec用来形容对象的冀望状态,以及对象的 一些根本信息(name kind),过后用API创立独享的时候,API在申请主体中应该蕴含JSON格局的数据,大部分状况下咱们提供的是.yaml文件来为kubectl提供这些信息,当kubectl发动API申请的时候,这些信息会被转换成JSON格局

上面是一个.yaml的示例

apiVersion: apps/v1kind: Deploymentmetadata:  name: nginx-deploymentspec:  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和可选的namespace
  • spec 所冀望的该对象的状态

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: v1kind: Podmetadata:  name: label-demo  labels:    environment: production    app: nginxspec:  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: v1kind: Podmetadata:  name: cuda-testspec:  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: v1kind: Podmetadata:  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.namemetadata.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

举荐应用的标签

除了kubectldashboard之外,还能够应用其余工具来可视化和治理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字符串