核心技术概念和API对象
API对象是Kubernetes集群中的管理操作单元。
Kubernetes集群系统每支持一项新功能,引如一项新技术,一定会新引入对应的API对象,支持对该功能的管理操作。
每个API对象都有四大类属性:
- TypeMeta
- MetaData
- Spec
- Status
TypeMeta
Kubernetes对象的最基本定义,它通过引入GKV(Group、Kind、Version)模型定义了一个对象的类型
- Group
将对象依据其功能范围归入不同的分组,比如把支撑最基本功能的对象归入core组,将与应用部署相关的对象归入apps组,会使这些对象的可维护性和可理解性更改。 - Kind
定义一个对象的基本类型,比如Node、Pod、Deployment等。 - Version
随着Kubernetes版本的演进,对象从创建之初到能够完全生产化就绪的版本是不断变化的。
Metadata
Metadata中有两个最重要的属性:Name和
-
name
定义了对象的名字。
-
namespace
定义了对象的Namespace归属。 -
Annotations
注解。是将任意非标识元数据(Kubernetes 不关心的元数据)附加到对象上,其存在形式是键值对。 -
Labels
标签。给对象打标签,一个对象可以有任意对标签,其存在形式是键值对。定义了对象的可识别属性,支持以Label作为过滤条件查询对象。
-
Finalizer
本质上是一个资源锁,Kubernetes在接收某对象的删除请求时,会检查Finalizer是否为空,如果不为空则只对其做逻辑删除,即只更新对象中meta.deletionTimestamp字段。 -
ResourceVersion
一种乐观锁,每个对象在任意时刻都有其ResourceVersion,当Kubernetes对象被客户端读取后,ResourceVersion信息也一并读取。此机制确保了分布式系统中任意多线程能够无锁并发访问对象,极大提高了系统的整体效率
Spec
用户的期望状态,由创建对象的用户端来定义。
Status
对象的实际状态,由对应的控制器收集实际状态并更新。
Kubernetes对象以及分组
核心对象
Node
Node是Pod真正运行的主机,可以物理机,也可以是虚拟机。为了管理Pod,每个Node节点上至少要运行container runtime 。
# 查看节点信息
kubectl get node `kubectl get node | awk 'NR==2{print $1}'` -o yaml
Namespace
Namespace 是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。
apiVersion: v1
kind: Namespace
metadata:
name: hjy
Pod
Pod是一组紧密关联的容器集合,它们共享PID、IPC、Network和UTS namespace,是Kubernetes调度的基本单位。
apiVersion: v1
kind: Pod
metadata:
name: pod1
namespace: hjy
annotations:
describe: "this is nginx pod test"
labels:
app: nginx
spec:
containers:
- name: nginx
image: hub.linx.com/k8s/nginx-test
PV/PVC
PV(Persistent Volumes)是持久化存储卷,通过存储卷可以把外挂存储挂载到Pod内部使用。存储卷定义包含两个部分:Volume和VolumeMounts。
- Volume:定义Pod可以使用存储卷来源;
- VolumeMounts:定义存储卷如何Mount到容器内部
ResoureQuota
ResourceQuota对象用来定义某个命名空间下所有资源的使用限额,其实包括:
- 计算资源的配额
- 存储资源的配额
- 对象数量的配额
-
启动资源配额
Kubernetes 的众多发行版本默认开启了资源配额的支持。当在apiserver的--admission-control
配置中添加ResourceQuota
参数后,便启用了。 当一个命名空间中含有ResourceQuota
对象时,资源配额将强制执行。 -
计算资源配额
可以在给定的命名空间中限制可以请求的计算资源(compute resources)的总量。
资源名称 | 描述 |
---|---|
cpu | 非终止态的所有pod, cpu请求总量不能超出此值。 |
limits.cpu | 非终止态的所有pod, cpu限制总量不能超出此值。 |
limits.memory | 非终止态的所有pod, 内存限制总量不能超出此值。 |
memory | 非终止态的所有pod, 内存请求总量不能超出此值。 |
requests.cpu | 非终止态的所有pod, cpu请求总量不能超出此值。 |
requests.memory | 非终止态的所有pod, 内存请求总量不能超出此值。 |
- 存储资源配额
可以在给定的命名空间中限制可以请求的存储资源(storage resources)的总量。
资源名称 | 描述 |
---|---|
requests.storage | 所有PVC, 存储请求总量不能超出此值。 |
persistentvolumeclaims | 命名空间中可以存在的PVC(persistent volume claims)总数。 |
.storageclass.storage.k8s.io/requests.storage | 和该存储类关联的所有PVC, 存储请求总和不能超出此值。 |
.storageclass.storage.k8s.io/persistentvolumeclaims | 和该存储类关联的所有PVC,命名空间中可以存在的PVC(persistent volume claims)总数。 |
- 对象数量的配额
资源名称 | 描述 |
---|---|
congfigmaps | 命名空间中可以存在的配置映射的总数。 |
persistentvolumeclaims | 命名空间中可以存在的PVC总数。 |
pods | 命名空间中可以存在的非终止态的pod总数。如果一个pod的status.phase 是 Failed, Succeeded , 则该pod处于终止态。 |
replicationcontrollers | 命名空间中可以存在的rc 总数。 |
resourcequotas | 命名空间中可以存在的资源配额(resource quotas)总数。 |
services | 命名空间中可以存在的服务总数量。 |
services.loadbalancers | 命名空间中可以存在的服务的负载均衡的总数量。 |
services.nodeports | 命名空间中可以存在的服务的主机接口的总数量。 |
secrets | 命名空间中可以存在的secrets 的总数量。 |
例如:可以定义pod的限额来避免某用户消耗过多的Pod IPs。
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
namespace: hjy
spec:
hard:
pods: "4"
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
scopeSelector:
matchExpressions:
- operator : In
scopeName: PriorityClass
values: ["low"]
ConfigMap
ConfigMap 用来将非机密性的数据保存到键值对中。
使用时,Pods 可以将其用作环境变量、命令行参数或者存储卷中的配置文件。
ConfigMap 将环境配置信息和 容器镜像解耦,便于应用配置的修改。
kind: ConfigMap
apiVersion: v1
metadata:
name: config6
namespace: hjy
labels:
app: config6
annotations:
kubesphere.io/alias-name: hjy
kubesphere.io/description: jyhe
data:
passwd: passwd
Secert
- Secret 是用来保存和传递密码、密钥、认证凭证这些敏感信息的对象。
- 使用 Secret 的好处是可以避免把敏感信息明文写在配置文件里。
- Kubernetes 集群中配置和使用服务不可避免的要用到各种敏感信息实现登录、认证等功能,例如访问 AWS存储的用户名密码。
apiVersion: v1
kind: Secret
metadata:
name: ceph-secret
type: "kubernetes.io/rbd"
data:
key: QVFDdENWdGtTRGN6SGhBQTNqUDZ3VkhWZ2pYVjgyZmlBbGljUUE9PQ==
Service
Deployment负责保持一组Pod处于运行状态,那么Service负责为一组Pod启动网络访问。Services可以跨集群提供标准化的特性:负载均衡、应用间的服务发现以及零宕机应用程序deployment。每个服务都有独一无二的IP地址以及DNS主机名称。
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
namespace: hjy
labels:
name: nginx-svc
spec:
type: ClusterIP
ports:
- protocol: TCP
port: 83
targetPort: 80
selector:
app: nginx
ServiceAccount
ServiceAccount是一种账号,给运行在Pod里面的进程提供必要的身份证明。
创建帐号
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: admin
namespace: hjy
帐号与角色绑定
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard-admin
labels:
k8s-app: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin
namespace: hjy
pod使用帐号
apiVersion: v1
kind: Pod
metadata:
name: pod
namespace: hjy
spec:
containers:
- name: nginx
image: nginx-test
serviceAccountName: admin
Event
事件(Event)通常用来记录集群内发生的状态变更,大到集群节点异常,小到 Pod 启动、调度成功等等。我们常用的kubectl describe命令和kubectl get events命令就可以查看相关资源的事件信息。
Endpoint
- endpoint是集群中的一个资源对象,储存在etcd中,用来记录一个service对应的pod的访问地址。
- service配置serlector,endpoint controler才会自动创建对应的endpoint对象;否则,则不会创建endpoint对象
kubectl get endpoints -A
StorageClass
StorageClass作为对存储资源的抽象定义,对用户设置的PVC申请屏蔽后端存储的细节,一方面减少了用户对存储资源细节的关注,另一方面减少了管理员手工管理PV的工作,由系统自动完成PV的创建和绑定,实现了动态的资源供应。
StorageClass的定义主要包括名称、后端存储的提供者(privisioner)和后端存储的相关参数配置。StorageClass一旦被创建,就无法修改,如需修改,只能删除重建。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nginx-storageclass
namespace: default
provisioner: kubernetes.io/rbd
reclaimPolicy: Retain # Delete
allowVolumeExpansion: true
mountOptions:
- discard
parameters:
monitors: 10.0.0.101:6789,10.0.0.102:6789,10.0.0.103:6789
pool: rbd
adminId: admin
adminSecretName: ceph-secret
adminSecretNamespace: "default"
userId: admin
userSecretName: ceph-secret
应用管理
Deployment
Deployment是指管理性能并指定 Pod 所需行为的 Kubernetes 对象。 它指定应用程序的生命周期,包括分配给应用程序的 Pod。 它提供了一种方法来传达应用程序所需的状态,控制器负责将当前状态更改为所需的状态。
部署自动执行启动 Pod 实例的过程,并确保它们按照定义在群集内的所有节点上运行。 管理员和 IT 专业人员使用部署来传达他们希望从应用程序获取的内容,然后 Kubernetes 会执行所有必要的步骤来创建应用程序的所需状态。
虽然部署定义了应用程序的运行方式,但它们并不能保证应用程序在群集中的位置。 例如,如果应用程序需要在每个节点上都有一个 Pod 实例,则需要使用 DaemonSet。 对于有状态应用程序,StatefulSet 会提供唯一的网络标识符、持久存储和有序部署/缩放。
Kubernetes 部署对象可用于:
- 部署副本集或 Pod。
- 纵向扩展或缩减应用程序的实例数。
- 更新应用程序的每个正在运行的实例。
- 将应用程序的所有正在运行的实例回滚到另一个版本。
- 暂停或继续部署。
yaml方式
vim nginx-deployment.yaml
编排文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-app
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginxapp
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
执行yaml文件:
kubectl apply -f nginx-deployment.yaml
验证:
kubectl get deployment.apps
kubectl get deployment
kubectl get deploy
kubectl get replicaset
kubectl get rs
kubectl get all
kubectl describe deployment nginx-app
kubectl get pods -o wide
curl http://172.16.189.77
curl http://172.16.235.138
清除:
kubectl delete -f nginx-deployment.yaml
kubectl delete deployment nginx-app
ReplicaSet
ReplicaSet 是一个进程,它运行 Pod 的多个实例并保持指定数量的 Pod 不变。 它确保在任意给定时间运行一组稳定的副本 Pod,这保证了有可用的指定数量的相同 Pod。
当某个 Pod 失败时,ReplicaSet 将启动一个新的 Pod 实例,并当正在运行的实例达到指定数量时进行纵向扩展。 反之,当创建了具有相同标签的实例时,它会纵向缩减或删除 Pod。
yaml方式
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx
labels:
tier: nginx
spec:
# 按你的实际情况修改副本数
replicas: 3
selector:
matchLabels:
tier: nginx
template:
metadata:
labels:
tier: nginx
spec:
containers:
- name: nginx
image: nginx-test
StatefulSet
StatefulSet:维护超出单个 Pod 生命周期的应用程序的状态。 与部署一样,StatefulSet 创建并管理至少一个具有唯一、持久标识和稳定主机名的相同 Pod。 StatefulSet 中的副本使用顺序方法来进行部署、缩放和升级。
StatefulSet 适合需要稳定且唯一的标识符、持久存储、有序部署和缩放的应用程序。 这类应用的例子包括 MySQL、MongoDB、Kafka 和 Cassandra。 无状态应用程序(如 Apache 和 Tomcat)并不关心它们正在使用的网络,也不需要持久存储。
StatefulSet 的主要组件是永久性卷预配程序以及无外设服务。
yaml方式
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx
labels:
tier: nginx
spec:
# 必须指定一个server
serviceName: nginx-svc
# 按你的实际情况修改副本数
replicas: 3
selector:
matchLabels:
tier: nginx
template:
metadata:
labels:
tier: nginx
spec:
containers:
- name: nginx
image: nginx
DaemonSet
DaemonSet 是一个 Kubernetes 对象,可确保配置中定义的 Pod 副本始终在群集中的每个工作器节点上可用。 将新节点添加到群集时,DaemonSet 会自动分配该节点上的 Pod。
同样,删除节点时,该节点上运行的 Pod 也会被删除,并且不会在另一个节点上重新计划 (,例如,与 ReplicaSets) 一样。 这使你能够克服 Kubernetes 计划限制,并确保在群集中的所有节点上部署特定的应用程序。
DaemonSet 可提高整体群集性能。 例如,可使用它们来部署 Pod,以执行维护任务,并针对每个节点提供支持服务:
- 运行日志收集守护程序,例如
Fluentd
和Logstash
。 - 运行监视守护程序的节点,例如
Prometheus
。 - 运行群集存储守护程序,例如
glusterd
或ceph
。
尽管 DaemonSet 默认在每个节点上创建 Pod,但可通过在 YAML 文件中预定义节点选择器字段来限制可接受节点的数量。 DaemonSet 控制器只会在与节点选择器匹配的节点上创建 Pod。
通常,一个 DaemonSet 可跨所有节点部署一个守护程序类型,但可能有多个 DaemonSet 使用不同的标签控制一个守护程序类型。 Kubernetes 标签根据各个节点的特征指定部署规则。
yaml方式
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app: nginx
name: example-daemon
spec:
template:
metadata:
labels:
app: nginx
spec:
containers:
-name: nginx
image: nginx
Job
普通任务是一次性运行的短任务,部署完成后即可执行。正常退出(exit 0)后,任务即执行完成。
普通任务是用来控制批处理型任务的资源对象。批处理业务与长期伺服业务(Deployment、Statefulset)的主要区别是:
批处理业务的运行有头有尾,而长期伺服业务在用户不停止的情况下永远运行。Job管理的Pod根据用户的设置把任务成功完成就自动退出了。成功完成的标志根据不同的spec.completions策略而不同,即:
- 单Pod型任务有一个Pod成功就标志完成。
- 定数成功型任务保证有N个任务全部成功。
- 工作队列型任务根据应用确认的全局成功而标志成功。
yaml方式
apiVersion: batch/v1
kind: Job
metadata:
name: myjob
spec:
completions: 50 # Job结束需要运行50个Pod,这个示例中就是打印1 50次
parallelism: 5 # 并行5个Pod
backoffLimit: 5 # 最多重试5次
template:
spec:
containers:
- name: nginx
image: nginx
command: ["echo", "1"]
restartPolicy: Never
CronJob
定时任务是按照指定时间周期运行的短任务。使用场景为在某个固定时间点,为所有运行中的节点做时间同步。
定时任务是基于时间的Job,就类似于Linux系统的crontab,在指定的时间周期运行指定的Job,即:
- 在给定时间点只运行一次。
- 在给定时间点周期性地运行。
CronJob的典型用法如下所示:
- 在给定的时间点调度Job运行。
- 创建周期性运行的Job,例如数据库备份、发送邮件。
yaml方式
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure