之前“Kubernetes基本架构及集群部署”中介绍了Kubernetes的基本架构、功能组件以及部署,本文继续基于张建锋老师容器技术培训内容整理介绍Kubernetes的一些基础的资源对象,包括Pod、有状态和无状态的Workload、Service以及Volume等。
1、K8S基础资源构成
-
工作负载 (Workload)
-
发现和负载均衡 (Discovery & LB),Service / Endpoint /Ingress
-
配置和存储 (Config & Storage),ConfigMap / Secret /Volumn
-
集群 (Cluster),Namespace / Node / Role / ClusterRole /RoleBinding / ClusterRoleBinding
-
元数据 (Metadata),HPA / LimitRange
1.1 API对象
1.1.1 API对象基本组成
-
kind:对象(objects)系统中的永久资源;列表(list)一个或多个资源类别的集合;简单类别(simple)包含作用在对象上的特殊行为和非持久实体
-
apiVersion:API版本
-
metadata元数据:标识API对象。API对象至少含有3个元数据:namespace,name,uid
-
spec:期望状态。API对象通过spec去设置配置;用户通过配置系统的理想状态来改变系统 , 所有的操作都是声明(Declarative)的而不是命令式(Imperative)的 ;声明式操作在分布式系统中的好处是稳定,不怕丢操作或运行多次 。
-
status:实际状态,对象部署后将当前的状态更新到status中。Pod的status信息主要包括conditions、phase、podIP、startTime等,其中phase描述对象所处的生命周期阶段、condition表示条件,由条件类型和状态值组成。
以下是简单的Deployment的yaml定义:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: nginx-example
labels:
apps: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
status: {}
1.1.2 Label标签
-
一个label会以kv形式附加到各种对象上:Node、Pod、Service、RS。同一个资源对象的labels属性的key必须唯一
-
一个资源对象可以定义任意多数量的Label,同一个Label也可以被添加到任意数量的资源对象上去;
-
label通常在资源对象确定时定义,也可以在资源创建后动态添加或删除;
-
版本标签(release):stable(稳定版),canary(金丝雀版本),beta(测试版)
-
环境类(environment):dev(开发),qa(测试),production(生产),op(运维)
-
应用类(applaction):ui(设计),as(应用软件),pc(电脑端),sc(网络方面)
-
架构层(tier):frontend(前端),backend(后端),cache(缓存)
-
分区标签(partition):customerA(客户),AreaB(区域)
-
质量管控级别(track):daily(每天),weekly(每周)
Kubernetes通过label selector查询和筛选拥有某些Label的资源对象,这种方式类似于SQL的where查询条件,比如name=redis-slave匹配所有name=redis-slave的资源对象、env!=production匹配所有不具有标签env=production的资源对象。
1.2 NameSpace
-
为团队创建不同Namespace
-
为开发、测试、生产环境创建不同的Namespace,以做到彼此之间相互隔离
-
可以使用 ResourceQuota 与Resource LimitRange 限制资源分配与使用
Kubernetes集群初始有三个命名空间,分别是default、kube-system和kube-public,除此以外,管理员可以创建新的命名空间满足需要。一旦创建了Namespace,可以在创建资源对象的时候指定资源对象属于哪个NameSpace。
1.3 基础构成POD
官方对于Pod的解释是:
Pod是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。
Pod有两种类型普通的Pod和静态Pod,静态Pod比较特殊,它并没有存放在K8S的etcd存储中,而是存放在某个具体的Node的一个具体文件中,并且只在此Node上启动运行。普通的Pod一旦被创建,就会放入etcd存储,随后被K8S Master调度到某个具体的Node上并进行绑定,随后该Pod被Kubelet进程实例化为一组Docker容器并启动。
1.3.1 创建POD
K8S中的所有对象都可以通过yaml来定义,以下是Pod的yaml文件:
apiVersion: v1
kind: Pod
metadata:
name: memory-demo
namespace: mem-example
spec:
containers:
- name: memory-demo-ctr
image: polinux/stress
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
volumeMounts:
- name: redis-storage
mountPath: /data/redis
volumes:
- name: redis-storage
-
apiVersion记录K8S的API Server版本,现在为v1
-
kind记录该yaml的对象类型,这里是Pod
-
metadata记录了Pod自身的元数据,比如Pod的名称、Pod属于哪个namespace
-
spec记录了Pod内部所有的资源的详细信息:
-
containers记录了Pod内的容器信息,包括:name容器名、image容器的镜像地址,resources容器需要的CPU、内存、GPU等资源,comman容器的入口命令,args容器的入口参数,volumeMounts容器要挂载的Pod数据卷等
-
volumes记录了Pod内的数据卷信息
1.3.2 POD创建过程
-
用户通过kubectl命名发起请求。
-
apiserver通过对应的kubeconfig进行认证,认证通过后将yaml中的po信息存到etcd
-
Controller-Manager通过apiserver的watch接口发现了pod信息的更新
-
执行该资源所依赖的拓扑结构整合,整合后将对应的信息交给apiserver
-
apiserver写到etcd,此时pod已经可以被调度了
-
Scheduler同样通过apiserver的watch接口更新到pod可以被调度,通过算法给pod分配节点
-
并将pod和对应节点绑定的信息交给apiserver
-
apiserver写到etcd,然后将pod交给kubelet
-
kubelet收到pod后,调用CNI接口给pod创建pod网络
-
调用CRI接口去启动容器,调用CSI进行存储卷的挂载
-
网络,容器,存储创建完成后pod创建完成,等业务进程启动后,pod运行成功
1.4 工作负载
Kubernetes集群中的Workload工作负载根据不同业务分为以下:
业务类型 | API对象 |
---|---|
无状态 | ReplicaSet、Deployment |
有状态 | StatefulSet |
后台持续服务 | DaemonSet |
批处理型 | Job |
1.4.1基础构成ReplicaSet
-
通过定义RS实现Pod创建及副本数量的自动控制
-
RS中包括完整的Pod定义模板
-
通过Label Selector机制实现对Pod副本的自动控制
-
通过改变RS里Pod副本数量,可以实现Pod的扩容与缩容
-
通过改变RS中Pod模板的镜像版本,可以实现Pod的滚动升级
需要注意的是一般很少单独使用ReplicaSet,主要被Deployment这个更高层的资源对象引用,从而形成一整套Pod的创建、删除和更新的编排机制。
1.4.2 基础构成Deployment
Deployment的典型使用场景如下:
-
创建一个Deployment对象来生成对应的Replica Set并完成Pod副本的创建
-
检查Deployment的状态来看部署动作是否完成(Pod副本数量是否达到预期的值)
-
更新Deployment以创建新的Pod
-
如果当前Deployment不稳定,则回滚到一个早先的Deployment版本
-
暂停Deployment以便于一次性修改多个PodTemplateSpec的配置项,之后再恢复Deployment,进行新的发布
-
扩展Deployment以应对高负载
-
查看Deployment的状态,以此作为发布是否成功的指标
-
清理不再需要的旧版本ReplicaSets
Deployment的定义如下所示,声明最终的部署结果,执行具体过程由kubernetes完成
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: kubia
spec:
replicas: 3
template:
metadata:
name: kubia
labels:
app: kubia
spec:
containers:
- image: luksa/kubia:v1
name: nodejs
运行下面命令创建Deployment
# kubectl create -f tomcat-deployment.yaml
运行下面命令查看Deployment信息:
# kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AGE
tomcat-deploy 1 1 1 4h
-
DESIRED:Pod副本数量的期望值,即在Deployment里定义的Replica。
-
CURRENT:当前Replica的值,实际上是Deployment创建的Replica Set里的Replica值,这个值不断增加,直到达到DESIRED为止,表明整个部署过程完成。
-
UP-TO-DATE:最新版本的Pod的副本数量,用于指示在滚动升级的过程中,有多少个Pod副本已经成功升级。
-
AVAILABLE:当前集群中可用的Pod副本数量,即集群中当前存活的Pod数量
1.4.3 组成部分StatefulSet
-
每个节点都有固定的身份ID,通过这个ID,集群中的成员可以相互发现并通信;
-
集群的规模是比较固定的,集群规模不能随意变动;
-
集群中的每个节点都是有状态的,通常会持久化数据到永久存储中;
-
如果磁盘损坏,则集群里的某个节点无法正常运行,集群功能受损。
-
StatefulSet里每个Pod都要稳定的、唯一的网络标识,可以用来发现集群内的其它成员。StatefulSet 中的每个 Pod 的名字都是事先确定的,不能更改。
-
StatefulSet控制的Pod的启停顺序是有依赖的,操作第n个Pod,前n-1个Pod已经运行且准备好
-
StatefulSet 中的 Pod,每个 Pod 挂载自己独立的存储,通过PV或PVC来实现,删除Pod时默认不会删除与StatefulSet相关的存储卷。如果一个 Pod 出现故障,从其他节点启动一个同样名字的 Pod,要挂载上原来 Pod 的存储继续以它的状态提供服务。
适合于StatefulSet的业务包括数据库服务MySQL和PostgreSQL、集群化管理服务ZooKeeper、etcd等有状态服务。StatefulSet的另一种典型应用场景是作为一种比普通容器更稳定可靠的模拟虚拟机的机制。使用 StatefulSet,Pod仍然可以通过漂移到不同节点提供高可用,而存储也可以通过外挂的存储来提供高可靠性,StatefulSet做的只是将确定的 Pod 与确定的存储关联起来保证状态的连续性。
1.4.4 后台支撑服务集DaemonSet
1.4.5 组成部分job
-
单Pod型任务有一个Pod成功就标志完成
-
定数成功型任务保证有N个任务全部成功,需设定参数.spec.completions
-
工作队列型任务根据应用确认的全局成功而标志成功
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cronjob
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cronjob
image: busybox
command: ["/bin/sh","-c","date"]
restartPolicy: Never
-
Job Template Expansion模式:一个Job对象对应一个待处理的Work item,适用于Work item数量少每个work item需要处理大数据量的场景
-
Queue with Pod Per Work Item模式:采用任务队列存放Work item,一个job对象作为消费者去完成这些Work item;这种模式下会启动N个Pod,每个Pod对应一个Work item
-
Queue with Variable Pod Count模式:也是采用任务队列存放work item,不同的是Job启动的Pod数量是可变的
1.5 基础构成Service
如果要稳定地提供服务需要服务发现和负载均衡能力:
-
服务发现完成的工作,是针对客户端访问的服务,找到对应的的后端服务实例。在K8S集群中,客户端需要访问的服务就是Service对象。每个Service会对应一个集群内部有效的虚拟 IP,集群内部通过虚拟IP访问一个服务。
-
Kubernetes内部的负载均衡是由Kube-proxy实现的,Kube-proxy是一个分布式代理服务器,部署在K8S的每个节点上,负责把Service的请求转发到后端的某个Pod实例上,并在内部实现服务的负载均衡与会话保持机制;Kube-proxy在设计体现了它的伸缩性优势,需要访问服务的节点越多,提供负载均衡能力的 Kube-proxy 就越多,高可用节点也随之增多。
1.6 基础构成Volume
-
启动时需要的初始数据,可以是配置文件
-
启动过程中产生的临时数据,该临时数据需要多个容器间共享
-
启动过程中产生的持久化数据
以上都不希望在容器重启时就消失,存储卷由此而来,K8S中可以根据不同场景提供不同类型的存储能力。K8S中支持的存储类型如下:
#hostPath – 挂载主机磁盘到容器
#NFS/NAS –挂载共享文件系统
#emptyDir
#awsElasticBlockStore / azureFileVolume
#Glusterfs
#Ceph rbd / Cephfs
1.6.1 持久化存储卷PersistentVolume
-
PV只能是网络存储,不属于任何Node,但可以在每个Node上访问
-
PV不是定义在Pod上的,而是独立于Pod之外定义的
Provisioning(配置)--->Binding(绑定)--->Using(使用)--->Releasing(释放)--->Recycling(回收)
PV的创建有两种模式:静态模式和动态模式,静态模式下除了创建PVC外,还需要手动创建PV。
apiVersion: v1
kind: PersistentVolume
metadata:
name: mongodb-nfs-pv
namespace: default
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy:Retain
storageClassName: nfs-mongodb
nfs:
path: /root/data/nfs/mongodb
server: 192.168.72.100
-
PV的accessModes属性,支持三种类型
-
ReadWriteMany 多路读写,卷能被集群多个节点挂载并读写
-
ReadWriteOnce 单路读写,卷只能被单一集群节点挂载读写
-
ReadOnlyMany 多路只读,卷能被多个集群节点挂载且只能读
-
persistentVolumeReclaimPolicy:当与之关联的PVC被删除以后,这个PV中的数据如何被处理
-
Retain:当删除与之绑定的PVC时候,这个PV被标记为released且之前的数据依然保存在该PV上,但是该PV不可用,需要手动来处理这些数据并删除该PV
-
Delete:当删除与之绑定的PVC时候
1.7 基础构成配置项
-
在运行时通过容器的环境变量来传递参数
-
通过Docker Volume将容器外的配置文件映射到容器内
-
ConfigMap将所有的配置项当作key-value的字符串,然后这些配置项作为Map表中的一个项,整个Map中的数据持久化的存储在Kubernetes的ETCD数据库中,最后提供API方便Kubernetes相关组件或者应用CURD操作这些数据;
-
Kubernetes提供了一种内建机制,将存储在etcd中的ConfigMap通过Volume映射的方式变成目标Pod内的配置文件,不管目标Pod被调度到哪台服务器上,都会完成自动映射。如果ConfigMap中的key-value数据被修改,则映射到Pod中的“配置文件”也会随之自动更新。

2、总结
参考资料:
-
容器技术培训,张建峰老师
-
Kubernetes权威指南第4版,龚正等编著
-
https://kubernetes.io/zh/docs/home/
-
https://blog.csdn.net/Tencent_TEG/article/details/111877836
-
https://blog.csdn.net/qq_37419449/article/details/122157277
原文始发于微信公众号(牧羊人的方向):Kubernetes基础资源对象介绍
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/65081.html