Kubernetes:Controller
标签:实现 har data write record running 部分 回收 pre
简介
Kubernetes集群中的Controller对象可以创建和管理多个Pod,提供副本管理、健康检查、滚动升级和集群级别的自愈能力。例如,如果一个节点故障,Controller就能自动将该节点上的Pod调度到其他健康的节点上。这些Controller运行在Kubernetes集群的主节点上,它们不断控制集群中的资源向期望状态迁移(stauts -> spec)。常用的Controller类型有:
ReplicaSet
Deployment
DaemonSet
StatefulSet
Job/Cronjob
ReplicaSet
决定一个Pod有多少同时运行的副本,并保证这些副本的期望状态与当前状态一致。
配置
一个典型的ReplicaSet配置如下:
apiVersion: apps/v1 kind: ReplicaSet metadata: name: frontend labels: app: guestbook tier: frontend spec: replicas: 3 # 副本数 selector: matchLabels: tier: frontend template: metadata: labels: tier: frontend spec: containers: - name: php-redis image: docker.io/redis:latest
在上述配置信息中,字段
spec.template.metadata.labels
的值必须与spec.selector
值相匹配,否则创建请求会被Kubernetes API拒绝;被ReplicaSet控制的Pod在创建或更新后,其
metadata.ownerReferences
字段会添加该ReplicaSet的信息;一旦删除了原来的ReplicaSet,就可以创建一个新的来替换它。只要新旧ReplicaSet的
spec.selector
字段是相同的,新的ReplicaSet便会接管原有的Pod。然而,修改ReplicaSet中的template并不会使其接管的Pod的Spec更新。
应用场景
重调度:保证指定数量的Pod正常运行;
弹性伸缩:修改
spec.replicas
字段,实现Pod数量弹性伸缩;应用多版本追踪:修改
spec.selector
字段,实现对一个Pod的多版本管理。
由于ReplicaSet并不支持使用命令kubectl roll-update对Pod进行滚动更新,因此若想要以可控的方式更新Pod,建议使用Deployment。
Deployment
Deployment为Pod和ReplicaSet提供声明式的更新能力,用于管理无状态的应用。
配置
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: docker.io/nginx:latest ports: - containerPort: 80
.spec.selector
字段必须匹配.spec.template.metadata.labels
,否则请求会被Kubernetes API拒绝;当Pod的标签和Deployment的标签选择器匹配,但其模板和
.spec.template
不同,或者此类Pod的总数超过.spec.replicas
的设置时,Deployment会将其终止;如果Pod的总数未达到期望值,Deployment会基于
.spec.template
创建新的Pod。
创建
[root@test-master1 ~]# kubectl create -f test.yml --record deployment.apps/nginx-deployment created [root@test-master1 ~]# kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 3 3 3 9s
查看上线状态
[root@test-master1 ~]# kubectl rollout status deployment.v1.apps/nginx-deployment deployment "nginx-deployment" successfully rolled out [root@test-master1 ~]# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-deployment-5cbbd6c556-gj4vp 1/1 Running 0 4m app=nginx,pod-template-hash=1766827112 nginx-deployment-5cbbd6c556-vk4vl 1/1 Running 0 4m app=nginx,pod-template-hash=1766827112 nginx-deployment-5cbbd6c556-z24z8 1/1 Running 0 4m app=nginx,pod-template-hash=1766827112 [root@test-master1 ~]# kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-5cbbd6c556 3 3 3 2d
查看详细信息
[root@test-master1 ~]# kubectl describe rs nginx-deployment-5cbbd6c556 Name: nginx-deployment-5cbbd6c556 Namespace: gwr Selector: app=nginx,pod-template-hash=1766827112 Labels: app=nginx pod-template-hash=1766827112 ...
其中一些参数的含义:
NAME:列出了集群中Deployment的名称;
READY:应用程序的可用的副本数,显示的格式是“就绪个数/期望个数”;
UP-TO-DATE:为了达到期望状态已经更新的副本数;
AVAILABLE:显示应用可供用户使用的副本数;
AGE:显示应用程序运行的时间。
我们可以发现ReplicaSet被命名为Deployment名称加一个数字的格式(nginx-deployment-5cbbd6c556),这个数字是使用Pod标签中pod-template-hash
字段作为种子随机生成的。而此标签字段是通过对Pod的template进行哈希处理得到的,可确保Deployment管理的ReplicaSet不重叠。
更新
使用kubectl edit deployment <deployment-name>命令,可直接对Deployment管理的Pod进行更新。当使用kubectl describe deployments命令查看更新信息时,可以在Events下看到更新的过程:
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 2m deployment-controller Scaled up replica set nginx-deployment-2035384211 to 3 Normal ScalingReplicaSet 24s deployment-controller Scaled up replica set nginx-deployment-1564180365 to 1 Normal ScalingReplicaSet 22s deployment-controller Scaled down replica set nginx-deployment-2035384211 to 2 Normal ScalingReplicaSet 22s deployment-controller Scaled up replica set nginx-deployment-1564180365 to 2 Normal ScalingReplicaSet 19s deployment-controller Scaled down replica set nginx-deployment-2035384211 to 1 Normal ScalingReplicaSet 19s deployment-controller Scaled up replica set nginx-deployment-1564180365 to 3 Normal ScalingReplicaSet 14s deployment-controller Scaled down replica set nginx-deployment-2035384211 to 0
当第一次创建Deployment时,它自动创建了一个ReplicaSet(nginx-deployment-2035384211)并将其管理的Pod扩容至3个副本;
更新Deployment时,它又创建了一个新的ReplicaSet(nginx-deployment-1564180365),并将其管理的Pod数量设置为1,然后将旧ReplicaSet管理的Pod缩容到2,以便至少有2个Pod可用且最多创建4个Pod;
然后,它使用相同的滚动更新策略继续对新的ReplicaSet扩容并对旧的ReplicaSet缩容;
最终,新ReplicaSet管理的Pod副本数扩容至3个,旧ReplicaSet管理的Pod全部终止,更新完成;
在整个更新过程中,最多只有一个Pod副本不提供服务,且同一时刻不会有过多的Pod副本同时运行(默认最多比预期值多一个)。
回滚
当Deployment不稳定时(例如进入反复崩溃状态),我们需要对其进行回滚操作。默认情况下,Deployment的所有上线记录都保留在系统中,以便可以随时回滚。
查看历史版本:kubectl rollout history deployment <deployment-name>
回滚至历史版本:kubectl rollout undo deployment <deployment-name> --to-revision=<deployment-version>
StatefulSet
StatefulSet用于管理有状态的应用程序,被其管理的Pod有一个按顺序增长的ID。它与Deployment最大的不同在于,StatefulSet始终将一系列不变的名字分配给Pod,这些Pod从同一个模板创建但并不能相互替换且每个Pod都对应一个特有的持久化存储标识。
应用场景
每个Pod拥有稳定的、唯一的网络标识符(DNS Name)
每个Pod拥有稳定的、持久的存储(PersistentVolume)
有序的、优雅的部署和缩放
有序的、自动的滚动更新
配置
apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: selector: matchLabels: app: nginx # has to match .spec.template.metadata.labels serviceName: "nginx" replicas: 3 # by default is 1 template: metadata: labels: app: nginx # has to match .spec.selector.matchLabels spec: terminationGracePeriodSeconds: 10 # not 0 containers: - name: nginx image: k8s.gcr.io/nginx-slim:0.8 ports: - containerPort: 80 name: web volumeMounts: - name: www mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: www spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "my-storage-class" resources: requests: storage: 1Gi
名为nginx的Headless Service用来给每个Pod配置DNS Name;
名为web的StatefulSet中的字段
spec.replicas
和spec.template.spec
字段表明将在独立的3个Pod副本中启动nginx容器;volumeClaimTemplates
字段表明将通过PersistentVolumes来为Pod提供持久化存储。
Pod标识
StatefulSet管理的Pod具备一个唯一标识,该标识由以下几部分组成:
序号:假设一个StatefulSet的副本数为N,其中的每一个Pod都会被分配一个序号,序号的取值范围从0到N-1,并且该序号在StatefulSet内部是唯一的。
稳定的网络标识:
StatefulSet中每个Pod根据StatefulSet的名称和Pod的序号派生出它的主机名hostname:<StatefulSet name>-<Pod 序号>;
StatefulSet可以使用Headless Service来控制其Pod所在的域,该域(domain)的格式为:<Service name>.<namespace>.svc.cluster.local("cluster.local"是集群的域名);
StatefulSet中每一个Pod将被分配一个DNS Name,格式为:<Pod name>.<所在域名>,因此可以直接通过该Pod的DNS Name访问到Pod。
稳定的存储:Kubernetes为每个VolumeClaimTemplate创建一个PersistentVolume。
部署和扩缩容
在默认情况下.spec.podManagementPolicy
字段值为OrderedReady,它代表依次进行Pod的部署和扩缩容:
在创建一个副本数为N的StatefulSet时,其Pod将被按{0...N-1}的顺序逐个创建;
在删除一个副本数为N的StatefulSet(或其中所有的Pod)时,其Pod将按照相反的顺序(即 {N-1...0})终止和删除;
在对StatefulSet执行扩容操作时,新增Pod所有的前序Pod必须处于Running(运行)和Ready(就绪)的状态;
终止和删除StatefulSet中的某一个Pod时,该Pod所有的后序Pod必须全部已终止。
若要并行管理Pod,需要设置.spec.podManagementPolicy
字段值为Parallel,此时StatefulSet将同时并行地创建或终止其所有的Pod。
更新
StatefulSet的更新策略有两种,它是通过定义spec.updateStrategy.type
字段的方式进行选择的。
On Delete:Controller将不会自动更新StatefulSet中的Pod,用户必须手动删除Pod以便让StatefulSet创建新的Pod,以此来对
spec.template
的变动作出反应。Rolling Updates
StatefulSet会删除和重建StatefulSet中的每个Pod,它将按照与Pod终止相同的顺序(从最大序号到最小序号)进行,每次更新一个Pod。它会等到被更新的Pod进入Running和Ready状态,然后再更新其前序Pod。
若Pod的template出错,导致Pod始终不能进入Running和Ready的状态,StatefulSet将停止滚动更新并一直等待(OrderedReady)。在修复template以后,StatefulSet将继续等待出错的Pod进入就绪状态,而该状态将永远无法出现。因此还必须删除所有已经尝试使用错误template的Pod,随后StatefulSet才会使用修复后的template重建Pod。
DaemonSet
DaemonSet确保全部(或者某些)节点上运行一个Pod的副本,且当有节点加入集群时,也会为他们新增一个Pod。当有节点从集群移除时,这些Pod同样会被回收。删除DaemonSet将会删除它所创建的所有Pod。
使用场景
在每个节点上运行集群守护进程glusterd、ceph等
在每个节点上运行日志收集守护进程fluentd、logstash等
在每个节点上运行监控守护进程Prometheus等
Spec配置
apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd-elasticsearch namespace: kube-system labels: k8s-app: fluentd-logging spec: selector: matchLabels: name: fluentd-elasticsearch template: metadata: labels: name: fluentd-elasticsearch spec: tolerations: # this toleration is to have the daemonset runnable on master nodes # remove it if your masters can‘t run pods - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: fluentd-elasticsearch image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2 resources: limits: memory: 200Mi requests: cpu: 100m memory: 200Mi volumeMounts: - name: varlog mountPath: /var/log - name: varlibdockercontainers mountPath: /var/lib/docker/containers readOnly: true terminationGracePeriodSeconds: 30 volumes: - name: varlog hostPath: path: /var/log - name: varlibdockercontainers hostPath: path: /var/lib/docker/containers
spec.template.spec.nodeSelector
字段指定运行Pod的节点,若不设置则默认在全部节点上运行;spec.template.spec.restartPolicy
字段的值默认是always,也必须是always。
调度策略
DaemonSet Controller将会向DaemonSet管理的的Pod添加spec.nodeAffinity
字段,并进一步由Kubernetes Scheduler将Pod绑定到目标节点。
nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchFields: - key: metadata.name operator: In values: - target-host-name
此外,容忍度(toleration)node.kubernetes.io/unschedulable:NoSchedule
将被系统自动添加到DaemonSet的Pod中。由此,默认调度器在调度DaemonSet的Pod时可以忽略节点的unschedulable属性。
通信
与DaemonSet中的Pod进行通信的几种可能模式如下:
Push:配置DaemonSet中的Pod,将更新发送到另一个服务,例如统计数据库;
节点IP和已知端口:DaemonSet中的Pod可以使用节点的端口,从而可以通过节点IP访问到Pod。客户端能通过某种方法获取节点IP列表,并且基于此也可以获取到相应的端口;
DNS:创建Headless Service并通过设置标签选择器选取Pod,通过使用Endpoints对象或从DNS服务中检索到多个A记录来发现DaemonSet;
Service:创建Service并通过设置标签选择器选取Pod,使用该Service随机访问到某个节点上的DaemonSet。由于Service的负载均衡机制,因此没有办法访问到特定节点。
Jobs
Job会创建一个或者多个Pods,并确保指定数量的Pod可以执行到Succeeded状态。随着Pods成功结束,Job跟踪记录成功完成的Pods个数。当数量达到指定的成功个数阈值时,Job结束。删除Job的操作会清除其创建的全部Pod。
配置
apiVersion: batch/v1 kind: Job metadata: name: pi spec: template: spec: containers: - name: pi image: perl command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] restartPolicy: Never backoffLimit: 4 # Job 最大的重试次数
spec.template.spec.restartPolicy
字段定义了Pod的重启策略,此处只允许使用Never和OnFailure两个取值;spec.completions
和spec.parallelism
字段值默认为1,代表Job只启动一个Pod;spec.completions
表示Job期望成功运行至结束的Pod数量。当该字段值大于1时,Job将创建至相应数量的Pod,编号为1-spec.completions
;spec.parallelism
表示并行运行的Pod数量。当该字段值大于1时,Job会依次创建相应数量的 Pod 并行运行,直到spec.completions
个Pod成功运行至结束;spec.activeDeadlineSeconds
字段指定Job的存活时长,该字段的优先级高于spec.backoffLimit
;Job终止后Pod不会被删除,可以通过定义
spec.ttlSecondsAfterFinished
字段实现自动清理Job以及Job管理的Pod。若字段值为100,则代表100秒后清理。若字段值为0,则代表Job完成后立即清理。
Endpoint Controller
负责维护Endpoint与其对应的Service的关系。Endpoint Controller会周期性地进行检查,确保它们始终运行在用户期望的状态。
GC Controller
在Kubernetes中,每一个从属对象都有一个metadata.ownerReferences
字段,标识其拥有者是哪一个对象。GC Controller会删除那些曾经有owner,后来又不再有owner的对象。
参考文献
https://kubernetes.io/docs/home/
https://kuboard.cn/learning/
标签:实现 har data write record running 部分 回收 pre
原文地址:https://www.cnblogs.com/koktlzz/p/14414016.html