ReplicaSet的目的是维护一组在任何时候都处于运行状态的Pod副本的稳定集合。因此,它通常用来保证给定数量的、完全相同的Pod的可用性。
ReplicaSet的工作原理
ReplicaSet是通过一组字段来定义的,包括一个用来识别可获得的pod的集合的选择符,一个用来标明应该维护的副本个数的数值,一个用来执行应该创建新Pod以满足副本个数条件时要使用的Pod模板等等。每个ReplicaSet都通过根据需要创建和删除Pod以使得副本个数达到期望值,进而实现其存在价值。当ReplicaSet需要创建新的Pod时,会使用所提供的Pod模板。
ReplicaSet通过Pod上的metadata.ownerReferences字段连接到附属Pod,该字段给出当前对象的属主资源。ReplicaSet所获得的Pod都在其ownerReferences字段中包含了属主ReplicaSet的标识信息、正是通过这一连接,ReplicaSet知道它所维护的Pod集合的状态,并据此计划其操作行为。
虽然ReplicaSet可以独立使用,但今天它主要被Deployment用作协调Pod创建、删除和更新的机制。当时用Deployment时,不必担心还要管理它们创建的ReplicaSet。Deployment会拥有并管理它们的ReplicaSet。
示例: replicaSet.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:name: nginx
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:name: nginxlabels:app: nginxspec:containers:- name: nginximage: nginxports:- containerPort: 80
一个Deployment控制器为Pods和ReplicaSets提供声明式的更新能力。
用户负责描述Deployment中的目标状态,Deployment控制器可以更改实际状态,使其变为期望的状态。用户可以定义Deployment以创建新的ReplicaSet,或删除现有的Deployment,并通过新的Deployment适配其资源。
Deployment典型使用场景:
创建Deployment
示例:nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx
spec:replicas: 2selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginxresources:limits:memory: "128Mi"cpu: "500m"ports:- containerPort: 80
[root@master k8s]# kubectl get all
NAME READY STATUS RESTARTS AGE
pod/nginx-67d4bdd6f5-p48dc 1/1 Running 0 11s
pod/nginx-67d4bdd6f5-rlrdq 1/1 Running 0 11sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 443/TCP 6d21hNAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx 2/2 2 2 11sNAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-67d4bdd6f5 2 2 2 11s
StatefulSet是用来管理有状态应用的工作负载API对象。
StatefulSet用来管理Deployment和扩展一组Pod,并且能为这些Pod提供序号和唯一性保证。
和Deployment相同的是,StatefulSet管理了基于相同容器定义的一组Pod。但和Deployment不同的是,StatefulSet为它们每个Pod维护了一个固定的ID。这些Pod是基于相同的声明来创建的,但是不能相互替换:无论怎么调度,每个Pod都有一个不变的ID。
StatefulSet和其他控制器使用相同的工作模式。在StatefulSet对象中定义了期望的状态,然后StatefulSet的控制器就会通过各种更新来达到想要的状态。
StatefulSet可以满足以下一个或多个需求的应用程序:
稳定意味着Pod调度或重调度的整个过程是有持久性的。如果应用程序不需要任何稳定的标识符或有序的部署、删除或伸缩,则应该使用由一组无状态的副本控制器提供的工作负载来部署应用程序,比如Deployment或者ReplicaSet可能更适合无状态应用部署需要。
限制
注意:headless使用场景:有时候创建的服务不想走负载均衡,想直接通过pod-id后链接后端,可以使用headless service。headless Service是将service的发布文件中的clusterip设置成none,不让其获取clusterip,DNS解析时直接走Pod。
示例: stateful.yaml
apiVersion: v1
kind: Service
metadata:name: nginxlabels:app: nginx
spec:ports:- port: 80name: webclusterIP: Noneselector:app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:name: web
spec:selector:matchLabels:app: nginx # has to match .spec.template.metadata.labelsserviceName: "nginx"replicas: 3 # by default is 1template:metadata:labels:app: nginx # has to match .spec.selector.matchLabelsspec:terminationGracePeriodSeconds: 10containers:- name: nginximage: nginxports:- containerPort: 80name: webvolumeMounts:- name: wwwmountPath: /usr/share/nginx/htmlvolumeClaimTemplates:- metadata:name: wwwspec:accessModes: [ "ReadWriteOnce" ]storageClassName: "my-storage-class"resources:requests:storage: 1Gi
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: my-storage-class
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
# Supported policies: Delete, Retain
reclaimPolicy: Delete
DaemonSet确保全部(或者某些)节点上运行一个Pod的副本。当有节点加入集群时,也会为它们新增一个Pod,当有节点从集群中移除时,这些Pod也会被回收。删除DaemonSet将会删除它创建的所有Pod。
DaemonSet典型用法:
通过默认调度器调度
DaemonSet确保所有符合条件的节点都运行该Pod的一个副本。通常,运行Pod的节点有Kubernetes调度器选择,不过,DaemonSet Pods由DaemonSet调度器创建和调度。这就带来一下问题:
ScheduleDaemonSetPods允许使用默认调度器而不是DaemonSet控制器来调度DaemonSet,方法是将NodeAffinity条件而不是.spec.NodeName条件添加到DaemonSet Pods。默认调度器接下来将Pod绑定到目标主机。如果DaemonSet Pod的节点亲和性配置已存在,则被替换。DaemonSet控制器仅在创建或修改DaemonSet pod时执行这些操作,不会更改DaemonSet的spec.template
此外,系统会自动添加 node.kubernetes.io/unschedulable: NoSchedule容忍度到DaemonSet Pod。在调度DaemonSet Pod时,默认调度器会忽略unSchedule节点
与DaemonSet中的Pod进行通信有几种模式:
如果节点的标签被修改,DaemonSet将立刻像新匹配上的节点添加Pod,同时删除不匹配的节点上的Pod。
可以修改DaemonSet创建的Pod。不过并非Pod的所有字段都可以更新。下次当某节点(即使具有相同的名称)被创建时,DaemonSet控制器还会使用最初的模板。
可以删除一个DaemonSet。如果使用kubectl并指定 --cascade=false选项,则Pod将被保留在节点上。接下来如果创建使用相同选择器的新DaemonSet,新的DaemonSet会收养已有的Pod。如果有Pod需要被替换,DaemonSet会根据其updateStrategy来替换。
init脚本
直接在节点上启动守护进程(例如使用init、upstartd、systemd)的做法当然是可行的,不过,基于DaemonSet来运行这些进程有如下好处:
和Deployment区别
DaemonSet与Deployment非常类似,他们都能创建Pod,并且Pod中的进程都不希望被终止(例如web服务器、存储服务器)。建议为无状态的服务使用Deployment,比如前端服务。对这些服务而言,对副本数量进行扩缩容、平滑升级,比精确控制Pod运行在某个主机上要重要的多。当需要Pod副本总是运行在全部或特定主机上,并需要他们优先于其他Pod启动时,应该使用DaemonSet。
Job会创建一个或者多个Pod,并确保指定数量的Pod成功终止,随着Pod成功结束,Job跟踪记录成功完成的Pod个数。当数量达到指定的成功个数阈值时,job结束。删除Job的操作会清楚所创建的全部pod。
一个简单的使用场景下,会创建一个Job对象以便以一种可靠的方式运行某Pod直到完成。当第一个Pod失败或者被删除(比如某些节点硬件失效或重启)时,Job对象会启动一个新的Pod。
也可以使用Job以并行方式运行多个Pod。
示例: job.yaml
apiVersion: batch/v1
kind: Job
metadata:name: myjob
spec:ttlSecondsAfterFinished: 100backoffLimit: 4template:spec:containers:- name: piimage: perlcommand: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]restartPolicy: Never
[root@master k8s]# kubectl get all
NAME READY STATUS RESTARTS AGE
pod/myjob-hx445 0/1 Completed 0 4sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 443/TCP 6d23hNAME COMPLETIONS DURATION AGE
job.batch/myjob 1/1 4s 4s
[root@master k8s]# kubectl logs myjob-hx445
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
[root@master k8s]#
上一篇:MySQL-视图
下一篇:创建型设计模式(C++)