kubernetes
的 API Server
以 RESTful
风格的编程接口将所有操作对象当作资源操作,并且可通过标准的 http/https
请求如 get、put、delete,post
等方式来实现,只不过通过 kubectl
的形式来实现
常用资源分类
- 一个应用通常需要多个资源的支持,例如使用
Deployment
管理Pod
、使用ConfigMap
资源保存应用配置、使用Service
或Ingress
暴露服务,使用Volume
提供外部存储等 - 依据资源的主要功能作为划分,
kubernetes
的API
对象大体可分为Workload
(工作负载) 、Discover&LB
(发现和负载均衡) 、Config&Storage
(配置和存储) 、Cluster
(集群) 和Metadata
(元数据)
工作负载型资源
pod
是工作负载型资源重的基础资源,但pod
资源可能会需要被重建,这类工作将由工作负载型的控制器来完成,其中ReplicationController
(上一代控制器其功能已经由ReplicaSet和Deployment负责实现) 、ReplicaSet
和Deployment
负责管理无状态应用SetatefulSet
用来管控有状态应用,还有些应用较为特殊,它们需要在集群中的每个节点上运行单个pod
资源,负责收集日志或运行服务系统等任务的系统级守护进程,这些pod
资源的管理则属于DaemonSet
管理,另外有些则应该在正常完成后退出,这些在正常完成后就应该推出的容器化应用由Job
负责- ReplicationController 用于确保每个 Pod 副本在任一时刻均能满足目标数量
- ReplicaSet 与 ReplicationController 唯一的不同之处在于支持的标签选择器不同, ReplicationController 只支持等值选择器,而 ReplicaSet 还额外支持给予集合的选择器
- Deployment 用于管理无状态的持久化应用,它用于为 pod 和 ReplicaSet 提供声明式更新,是构建在 ReplicaSet 之上更为高级的控制器
- StatefulSet 用于管理有状态的持久化应用,与其 Deployment 的不同之处在于 SeatefulSet 会为每个 Pod 创建一个独有的持久性标示符,并会确保各 Pod 之间的顺序性
- DaemonSet 用于确保每个节点都运行了某 Pod 的一个副本,新增的节点一样会被添加此类 Pod,反之会被收回
- Job 管理运行完成即可终止的应用
发现和负载均衡
Pod
资源需要固定的可被发现的方式,因为其随时可能被重建,另外Pod
资源仅在集群内可见,他的客户端也可能是集群内的其他Pod
资源,若要开放给集群外部网络中的用户访问则需要事先将其暴露到外部,并且要为同一种工作负载的访问流量进行负载均衡,Kubernetes
使用标准的资源对象来解决此类问题,他们是用来为工作负载添加发现与负载功能的Service
和Endpoint
以及通过七层代理实现请求流量负载均衡的Ingress
配置与存储
Docker
容器分层联合挂载的方式决定了不宜在容器内部存储需要持久化的数据,于是它通过引入挂载外部存储卷的方式来解决此类问题,而Kubernetes
则为此设计了Volume
它支持众多类型的存储设备或系统,另外还支持通过标准的 CSI 统一存储接口以及拓展支持更多类型的存储系统- 另外
Kubernetes
使用ConfigMap
资源,其能以环境变量或存储卷的方式接入到Pod
资源的容器中,并且可被多个同类的Pod
共享引用,不过并不适合存储敏感数据 Secret
资源用来存储敏感数据,如私钥与密码
集群级资源
- 用来定义集群自身配置信息的对象,主要包括这几种类型
Namespace
: 资源对象名称的作用范围,绝大多数对象都隶属于某个名称空间,如Deployment 、 Service
, 默认名称空间为Default
Node
:Kubernetes
集群的工作节点,标识符在当前集群中唯一Role
: 名称空间级别的由规则组成的权限集合,可被RoleBinding
引用ClusterRole
: Cluster级别的由规则组成的权限集合,可被RoleBinding
和ClusterRoleBinding
引用RoleBinding
: 将Role
中许可权限绑定在一个或一组用户之上,它隶属于且仅能作用于一个名称空间,绑定事可以引用同一名称空间的Role
,可以引用全局名称空间中的ClusterRole
ClusterRoleBinding
: 将ClusterRole
中定义的许可权限绑定在一个或一组用户之上,他能引用全局名称空间中的ClusterRole
,并能通过Subject
添加相关信息
元数据型资源
- 此类资源对象用于集群内部的其他资源配置其行为或特性,如
HorizontalPodAutoscaler
资源可用于自动伸缩工作负载类型的资源对象规模,Pod
模版资源用户为pod资源的创建预制模板,LimitRange
可为名称空间的资源设置CPU和内存等系统级资源的数量限制等
资源类型
-
资源类型
resource type
是指在URL中使用的名称,如 Pod、Namespace 和 Service 等,其URL格式为GROUP/VERSION/RESOURCE
,如apps/v1/deployment
所有资源类型都有一个对应的JSON表示格式,称为种类kind
客户端创建对象必须以JSON形式提交对象的配置信息,隶属于同一种资源类型的对象组成的列表称为集合collection
如PodList
,某种类型的单个实例称为资源resource
或对象object
,如名为pod-demo的Pod对象 -
Kubernetes将API分割为多个逻辑组合,称为API群组,它们支持单独启用或禁用,并能够再次分解。API Server支持在不同的群组中使用不同的版本,允许各组以不同的速度演进,而且也支持同一群组同时存在不同的版本,如
apps/v1、apps/v1beta2
和apps/v1beta1
,当前系统的API Server上的相关信息可通过kubectl api-versions
命令获取[root@master-0 ~]# kubectl api-versions admissionregistration.k8s.io/v1 admissionregistration.k8s.io/v1beta1 apiextensions.k8s.io/v1 apiextensions.k8s.io/v1beta1 apiregistration.k8s.io/v1 apiregistration.k8s.io/v1beta1 apps/v1 authentication.k8s.io/v1 authentication.k8s.io/v1beta1 authorization.k8s.io/v1 authorization.k8s.io/v1beta1 autoscaling/v1 autoscaling/v2beta1 autoscaling/v2beta2 batch/v1 batch/v1beta1 certificates.k8s.io/v1beta1 coordination.k8s.io/v1 coordination.k8s.io/v1beta1 discovery.k8s.io/v1beta1 events.k8s.io/v1beta1 extensions/v1beta1 networking.k8s.io/v1 networking.k8s.io/v1beta1 node.k8s.io/v1beta1 policy/v1beta1 rbac.authorization.k8s.io/v1 rbac.authorization.k8s.io/v1beta1 scheduling.k8s.io/v1 scheduling.k8s.io/v1beta1 storage.k8s.io/v1 storage.k8s.io/v1beta1 v1
-
Kubernetes
的API以层级结构组织在一起,每个API群组表现为一个以/apis
为根路径的REST路径,不过核心群组core有一个专用的简化路径/api/v1
目前,常用的API群组可归为如下两类- 核心群组
corgroup
:REST路径为/api/v1
,在资源的配置信息apiVersion字段中引用时可以不指定路径而仅给出版本,如apiVersion:v1
- 命名的群组
named group
:REST路径为/apis/$GROUP_NAME/$VERSION
例如/apis/apps/v1
它在apiVersion字段中引用的格式为apiVersion:$GROUP_NAME/$VERSION
,如apiVersion:apps/v1
。
- 核心群组
配置清单
-
apiserver
仅接收JSON
格式的资源定义,而yaml
更易用一些 -
当使用
yaml
格式提供配置清单,APIserver
可自动将格式转换为JSON
而后再提交 -
大部分资源的配置清单都由5个一级字段组成
apiVersion 、kind 、metadate 、spec
、status
- apiVersion:引用的api群组,
grep/version
- kind:类别,通过
metadata
定义某些类别而实例化出某种资源 - metadata:元数据,通常通用的字段包括
name 、namespace 、 labels 、 annotations ... ...
不过集群型类别可能不包括namespace - spec:期望状态
- status:实例状态
- apiVersion:引用的api群组,
-
通过使用
explain
可以查看对象类型和相应的嵌套字段[root@master-0 manifests]# kubectl explain pod [root@master-0 manifests]# kubectl explain pod.kind
yaml格式
- YAML:以数据为中心,比
json、xml
等更适合做配置文件
基本语法规则
- 大小写敏感
- 使用缩进表示层级关系
- 缩进时不允许使用Tab键,只允许使用空格。
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
支持的数据结构
- 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
- 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
- 纯量(数字、字符串、布尔值):单个的、不可再分的值
具体写法
-
纯量(数字、字符串、布尔值)
- k: v :字面量直接写,字符串默认不用加上单引号或者双引号
- 双引号:会转义特殊字符
- 单引号:不会转义字符串里边的特殊字符;特殊字符会作为本身想表示的意思
name: zhangsan age: 20 isBoss: false
-
数组
- 多行写法使用- 值来表示数组中的一个元素,需要注意缩进;单行使用
[值,值]
来表示一个数组
#多行结构 friends: - zhangsan - lisi - wangwu #单行结构 friend:[zhangsan,lisi,wangwu]
- 多行写法使用- 值来表示数组中的一个元素,需要注意缩进;单行使用
-
对象
- 多行写法:key:value的形式,使用多行写法需要注意缩进
- 单行写法:使用{key:value}的形式书写
#多行结构 friend: name:zhangsan age:20 #单行结构 friend:{name:zhangsan,age:20}
编写yaml格式的配置清单
-
编写文件
apiVersion: v1 kind: Pod metadata: name: pod-demo namespace: default labels: app: myapp tier: frontend spec: #必备字段,容器属性 containers: - name: myapp image: nginx ports: #不实际生效,仅仅作为info - name: http containerPort: 80 - name: https containerPort: 443 imagePullPolicy: IfNotPresent #镜像下载方式,Alway、Never、IfNotPresent,默认如果image为latest则默认Always,此字段为创建pod后不可修改 Cannot be updated - name: busbox image: busybox:latest command: - "/bin/sh" - "-c" - "sleep 36000"
- 修改镜像中的默认应用使用
command 、 args
其中与dockerfile中的cmd
与entrypolint
的关系为
command
类似entrypolint
而args
类似cmd
- 修改镜像中的默认应用使用
-
基于该文件创建并查看pod详情,最后删除pod
[root@master-0 manifests]# kubectl create -f demo.yaml pod/pod-demo created [root@master-0 manifests]# kubectl describe pod/pod-demo -n default ... ... [root@master-0 manifests]# kubectl delete -f demo.yaml pod "pod-demo" deleted
标签 labels
-
自定义字段,类似docker中
tag
的概念,是一组key value
字段,其中 key 和 value 的值长度必须小于等于63个字符 -
key只能使用字母与数字开头,特殊字符只能使用
_
、-
与.
-
value可以为空,只能使用字母或数字开头及结尾,中间可使用特殊符号
_
、-
与.
-
查看标签
[root@master-0 ~]# kubectl get po --show-labels NAME READY STATUS RESTARTS AGE LABELS deploy-765c7684d4-c456p 0/1 ImagePullBackOff 0 25d pod-template-hash=765c7684d4,run=deploy myapp-564fc884f-2czv8 1/1 Running 0 25d pod-template-hash=564fc884f,run=myapp myapp-564fc884f-cm9qb 1/1 Running 0 25d pod-template-hash=564fc884f,run=myapp myapp-564fc884f-jh6lf 1/1 Running 0 25d pod-template-hash=564fc884f,run=myapp myapp-564fc884f-k7bj7 1/1 Running 0 25d pod-template-hash=564fc884f,run=myapp myapp-564fc884f-kb57d 1/1 Running 0 25d pod-template-hash=564fc884f,run=myapp nginx-deploy-5df7f97d6f-t2clw 1/1 Running 0 25d pod-template-hash=5df7f97d6f,run=nginx-deploy nginx-node-f59db85f-sm9lb 1/1 Running 0 25d pod-template-hash=f59db85f,run=nginx-node nginx-nodes-9b585dbf5-gxvzp 1/1 Running 0 25d pod-template-hash=9b585dbf5,run=nginx-nodes nignx-668c45c884-lhvvd 1/1 Running 0 25d pod-template-hash=668c45c884,run=nignx pod-demo 2/2 Running 0 18d app=myapp,tier=frontend
-
显示标签类别
[root@master-0 ~]# kubectl get po -L NAME # 可为多个以 ,隔开 myapp-564fc884f-2czv8 1/1 Running 0 25d myapp-564fc884f-cm9qb 1/1 Running 0 25d myapp-564fc884f-jh6lf 1/1 Running 0 25d myapp-564fc884f-k7bj7 1/1 Running 0 25d myapp-564fc884f-kb57d 1/1 Running 0 25d nginx-deploy-5df7f97d6f-t2clw 1/1 Running 0 25d nginx-node-f59db85f-sm9lb 1/1 Running 0 25d nginx-nodes-9b585dbf5-gxvzp 1/1 Running 0 25d nignx-668c45c884-lhvvd 1/1 Running 0 25d pod-demo 2/2 Running 0 18d
-
显示拥有某个 key 的资源,并查看其键值信息
[root@master-0 ~]# kubectl get po -l app NAME READY STATUS RESTARTS AGE pod-demo 2/2 Running 0 18d [root@master-0 ~]# kubectl get po -l app --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-demo 2/2 Terminating 0 18d app=myapp,tier=frontend
-
为某项资源添加标签
kubectl label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]
[root@master-0 ~]# kubectl label pod pod-demo release=cancry pod/pod-demo labeled [root@master-0 ~]# kubectl get po -l app --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-demo 2/2 Terminating 0 18d app=myapp,release=cancry,tier=frontend
-
修改某项资源的标签,则通过覆盖的形式
--overwrite
[root@master-0 ~]# kubectl label pod pod-demo release=canary error: 'release' already has a value (cancry), and --overwrite is false [root@master-0 ~]# kubectl label pod pod-demo release=canary --overwrite pod/pod-demo labeled
标签选择器
-
标签选择器分为两种,等值关系与集合关系,如果指定多个多个选择条件,则内生隐含关系为逻辑域,选择条件必须同时满足
-
等值关系:
= == !=
[root@master-0 ~]# kubectl get pods -l release=canary NAME READY STATUS RESTARTS AGE pod-demo 2/2 Terminating 0 18d [root@master-0 ~]# kubectl get pods -l release==canary NAME READY STATUS RESTARTS AGE pod-demo 2/2 Terminating 0 18d [root@master-0 ~]# kubectl get pods -l release!=canary NAME READY STATUS RESTARTS AGE deploy-765c7684d4-5n7xm 0/1 Pending 0 20m deploy-765c7684d4-c456p 0/1 Terminating 0 25d myapp-564fc884f-2czv8 1/1 Terminating 0 25d myapp-564fc884f-56sxc 0/1 Pending 0 20m myapp-564fc884f-6mlp7 0/1 Pending 0 20m myapp-564fc884f-chlxx 0/1 Pending 0 20m myapp-564fc884f-cm9qb 1/1 Terminating 0 25d myapp-564fc884f-fbrcz 0/1 Pending 0 20m myapp-564fc884f-jh6lf 1/1 Terminating 0 25d myapp-564fc884f-k7bj7 1/1 Terminating 0 25d myapp-564fc884f-kb57d 1/1 Terminating 0 25d myapp-564fc884f-r24s2 0/1 Pending 0 20m nginx-deploy-5df7f97d6f-848vw 0/1 Pending 0 20m nginx-deploy-5df7f97d6f-t2clw 1/1 Terminating 0 25d nginx-node-f59db85f-qlczk 0/1 Pending 0 20m nginx-node-f59db85f-sm9lb 1/1 Terminating 0 25d nginx-nodes-9b585dbf5-fvtp5 0/1 Pending 0 20m nginx-nodes-9b585dbf5-gxvzp 1/1 Terminating 0 25d nignx-668c45c884-bp8gb 0/1 Pending 0 20m nignx-668c45c884-lhvvd 1/1 Terminating 0 25d [root@master-0 ~]# kubectl get pods -l release==canary,app=myapp # 逻辑域 NAME READY STATUS RESTARTS AGE pod-demo 2/2 Terminating 0 18d
-
集合关系:
KEY in (VALUE1,VALUE2, ... ...)
KEY notin (VALUE1,VALUE2, ... ...)
KEY
[root@master-0 ~]# kubectl get pods -l "release in (canary,beta)" NAME READY STATUS RESTARTS AGE pod-demo 2/2 Terminating 0 18d [root@master-0 ~]# kubectl get pods -l "release notin (canary,beta)" NAME READY STATUS RESTARTS AGE deploy-765c7684d4-5n7xm 0/1 Pending 0 28m deploy-765c7684d4-c456p 0/1 Terminating 0 25d myapp-564fc884f-2czv8 1/1 Terminating 0 25d myapp-564fc884f-56sxc 0/1 Pending 0 28m myapp-564fc884f-6mlp7 0/1 Pending 0 28m myapp-564fc884f-chlxx 0/1 Pending 0 28m myapp-564fc884f-cm9qb 1/1 Terminating 0 25d myapp-564fc884f-fbrcz 0/1 Pending 0 28m myapp-564fc884f-jh6lf 1/1 Terminating 0 25d myapp-564fc884f-k7bj7 1/1 Terminating 0 25d myapp-564fc884f-kb57d 1/1 Terminating 0 25d myapp-564fc884f-r24s2 0/1 Pending 0 28m nginx-deploy-5df7f97d6f-848vw 0/1 Pending 0 28m nginx-deploy-5df7f97d6f-t2clw 1/1 Terminating 0 25d nginx-node-f59db85f-qlczk 0/1 Pending 0 28m nginx-node-f59db85f-sm9lb 1/1 Terminating 0 25d nginx-nodes-9b585dbf5-fvtp5 0/1 Pending 0 28m nginx-nodes-9b585dbf5-gxvzp 1/1 Terminating 0 25d nignx-668c45c884-bp8gb 0/1 Pending 0 28m nignx-668c45c884-lhvvd 1/1 Terminating 0 25d
-
-
许多资源如支持内嵌字段定义其使用的标签选择器:
- matchLabels:直接给定键值
- matchExpressions:基于给定的表达式来定义使用的标签选择器,定义格式为:
{key:"KEY", operator:"OPERATOR",values:[VAL1,VAL2,...]}
意思是 KEY 这个健对 VAL1,VAL2,… 基于 OPERATOR 表达式做比较,能符合条件则表示符合需求否则不满足需求,operator 常用的有In
、NotIn
它们的 values 字段的值必须为非空列表 ,Exists
以及NotExists
它们的 values 字段的值必须为空列表
节点标签选择器
标签前可以追加前缀,其前缀必须是一个DNS域名或自域名,其长度最多为253个字符,这种格式通常出现在系统级资源上
[root@master-0 ~]# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
master-0.shared Ready master 26d v1.17.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master-0.shared,kubernetes.io/os=linux,node-role.kubernetes.io/master=
slave-0.shared NotReady <none> 26d v1.17.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=slave-0.shared,kubernetes.io/os=linux
slave-1.shared NotReady <none> 26d v1.17.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=slave-1.shared,kubernetes.io/os=linux
-
追加标签
[root@master-0 ~]# kubectl label nodes slave-0.shared disktype=ssd node/slave-0.shared labeled
-
当对节点追加标签后,添加资源时就可以让资源有倾向性,通过
nodeSelector
节点选择器实现[root@master-0 ~]# kubectl explain pods.spec.nodeSelector KIND: Pod VERSION: v1 FIELD: nodeSelector <map[string]string> DESCRIPTION: NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
-
nodeSelector 需要使用
matchLabels
或matchExpressions
给定[root@master-0 manifests]# cat demo1.yaml apiVersion: v1 kind: Pod metadata: name: pod-demo namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: nginx ports: - name: http containerPort: 80 - name: https containerPort: 443 imagePullPolicy: IfNotPresent - name: busbox image: busybox:latest command: - "/bin/sh" - "-c" - "sleep 36000" nodeSelector: #此外还可以使用nodeName指定该pod运行在哪个节点上 disktype: ssd [root@master-0 manifests]# kubectl create -f demo1.yaml pod/pod-demo1 created
-
annotations
-
同样是键值形式,但与label不同的地方在于它不能用于挑选资源对象仅用于为对象提供元数据,有些时候会被某些程序用到所以很重要,且没有字符限制还可以被
edit
动态编辑[root@master-0 ~]# kubectl delete pod-demo1 [root@master-0 ~]# cat demo1.yaml apiVersion: v1 kind: Pod metadata: annotations: magedu.com/created-by: cluster_admin name: pod-demo namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: nginx ports: - name: http containerPort: 80 - name: https containerPort: 443 imagePullPolicy: IfNotPresent - name: busbox image: busybox:latest command: - "/bin/sh" - "-c" - "sleep 36000" nodeSelector: disktype: ssd [root@master-0 ~]# kubectl create -f demo1.yaml pod/pod-demo created root@master-0 ~]# kubectl describe pod/pod-demo ... ... Annotations: magedu.com/created-by: cluster_admin ... ...