Kubernetes-Controller

0x00 Controller介绍

///

Q:什么是资源控制器?

A:k8s内建了很多控制器,控制Pod的具体状态和行为

Q:为什么要使用控制器?

A:Pod作为k8s部署的最小单元,而如果需要创建批量的Pod副本并进行扩容以及Pod的回退就需要controller进行实现

Q:有哪些类型的控制器?

A:1,Replication Controller 和 ReplicaSet;2,Deployment;3,DaemonSet;4,Job/CronJob;5,StatefulSet;6,Horizontal Pod Autoscaling;

0x01 Controller详细介绍

Replication Controller



Q:什么是Replication Controller(RC)?

A:Replication Controller是一个基本的控制类型,即是我们所说的RC(副本控制器),用于确保任意时间都有指定数量的Pod副本在运行

Q:RC的作用?

A:确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的Pod来替代,而如果容器由异常恢复到正常,那么多出来的容器也会自动回收

Q:RC工作原理是什么?

A:创建RC之后k8s Master节点上的Controller Manager组件接到创建RC的通知进行创建满足与副本数相应的Pod,然后它会定期巡视系统当中存活的目标Pod,然后进行标签匹配来监视对应的Pod,并确保目标Pod实例刚好等于RC中定义的副本数期望值,而目标Pod数超过副本期望值时,将会销毁多余的Pod

Q:RC组成部分?

A:1,Pod期待的副本数Replicas;2,用于筛选目标Pod的Label Selector,对应Pod模版(Template);3,Pod数量小于副本期望值时根据Pod模版创建相应的Pod


/RC示例//
# rc-demo.yaml
apiVersion: v1
kind: ReplicationController
metadata:
    name: rc-demo
spec:
    replicas: 3
    selector:
        app: nginx
    template:
        metadata:
            name: nginx
            labels:
                app: nginx
        spec:
            containers:
            - name: nginx
              image: nginx:latest
              ports:
              - containerPort: 80
# 操作实践
# 1,创建
kubectl apply -f rc-demo.yaml
# 2,获取创建好的信息
kubectl get rc/rc-demo
kubectl describe rc/rc-demo
# 3,获取Pod信息
kubectl get pod -l app=nginx
# 4,删除RC创建的Pod
kubectl delete pod nginx-*
# 5,删除RC
kubectl delete -f rc-demo.yaml


/RC Tips//
# 我们可以在删除RC时不删除其构建的Pod进行更新修改RC,可以采用delete命令子参数cascade=false。原RC被删除后可以创建一个新的RC来替换它,前提是旧的和新的spec.selector相匹配,那么新的RC将会接管旧的Pod
# 官方建议舍弃RC,切换使用功能更强的RS

ReplicaSet

Q:什么是ReplicaSet?

A:ReplicaSet(RS)副本集,RC的升级版本,区别在于名字不同而且RS支持集合式标签选择。这使得RS在资源选择上更加灵活

Q:ReplicaSet有什么作用?

A:和RC一样可以保持Pod副本数量。虽然RS可以独立使用,但是它主要用于协调Deployment对Pod的创建,删除和更新,当使用Deployment的时候不需要担心RS的功能,因为可以直接通过Deployment对其进行管理

Q:快速查看控制器的版本?

A:kubectl api-version | grep $(kubectl api-resources | grep "ReplicaSet" | awk -F " " '{print $3}')


//ReplicaSet示例
# replicaset-demo.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
    name: replicaset-demo
    labels:
        app: replicaset-demo
spec:
    replicas: 3
    selector:
        matchLabels:
            app: replicaset-demo
        matchExpressions:
            - {key: tier, operator: In, values: {frontend}}
    template:
        metadata:
            labels:
                app: replicaset-demo
        spec:
            containers:
            - name: nginx-replicaset-demo
              image: nginx:latest
              command: ["sh", "-c", "java -jar nginx-app-${RELASE_VER}.jar"]
              env:
              - name: GET_HOSTS_FROM
                value: dns
              - name: RELASE_VER
                value: 1.3.5
              ports:
              - containerPort: 80
EOF
# 操作流程
# 1,部署Rs-Pod
kubectl apply -f replicaset-demo.yaml
# 2,查看Pod
kubectl get pod --show-labels -o wide
# 3,查看Pod中的信息
kubectl exec replicaset-demo-xxxx -it -- env
# 4,删除所有Pod后,RS管理的Pod将会重启
kubectl delete pod --all
kubectl get pod --show-labels -o wide
# 5,删除RS,再删除Pod才算是真删除
kubectl delete rs replicaset-demo

Deployment

/

Q:什么是Deployment?

A:通过RS创建和管理对应的Pod,以及使用不同的RS交替完成滚动更新

Q:为什么要使用Deployment?

A:支持更新,回滚,可以简化部署流程。并且是全部在Deployment配置文件中完成。

Q:Deployment组成部分?

A:1,RS,Deployment生成RS并完成满足Pod副本数量的Pod创建;2,通过Deployment方便升级和回滚Pod应用;3,通过Deployment方便暂停或者恢复发布;4,通过Deployment方便扩容和缩容

Q:Pod,ReplicationController,ReplicaSet,Deployment的关系说明?

A:ReplicationController->Pod(一直满足Pod副本数除非RC被删除);ReplicaSet->Pod(一直满足pod副本数除非RS被删除,比RC的主要的特点是支持集合标签);Deployment->ReplicaSet->Pod(在RS的基础上快速完成更新回滚扩容和收缩)

Deployment如何完成更新,回滚,扩容和缩容

Deployment示例/

# nginx-deployment-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
    name: nginx-deployment-demo
spec:
    replicas: 3
    selector:
        matchLabels:
            app: nginx-deployment
    template:
        metadata:
            labels:
                app: nginx-deployment
        spec:
            containers:
            - name: nginx-deployment
              image: nginx:latest
              ports:
              - containerPort: 80

# 操作流程
# 1,部署,--record可以记录命令,可以查看每次reversion的变化
kubectl apply -f nginx-deployment-demo.yaml --record
# 2,查看
kubectl get deploy -o wide
kubectl get rs (rs也可以查看到Pod,以此证明Deployment并不是直接创建和管理Pod)
kubectl get pod -o wide --show-labels
# 3,访问nginx的html目录下的index.html
curl http://IP:Port
# 4,关于Deployment的扩容
kubectl scale deployment nginx-deployment-demo --replicas 5
kubectl autoscale deployment nginx-deployment-demo --min=10 --max=15 --cpu-percent # 如果集群支持horizontal pod autoscaling,可以设置自动扩容
# 5,关于更新容器中的镜像
kubectl set image deployment/nginx-deployment-demo nginx-deployment=redis:latest
kubectl get rs -o wide # 查看rs替换历史,可以看出已经替换了镜像
# 6,关于回滚和历史版本的控制
kubectl rollout undo deployment/nginx-deployment-demo # 执行回滚
kubectl rollout status deployment/nginx-deployment-demo # 查看回滚执行状态
kubectl rollout history deployment/nginx-deployment-demo # 查看回滚历史
# 7,编辑Deployment
kubectl edit deployment/nginx-deployment-demo
# 8,收缩
kubectl scale deployment nginx-deployment-demo --replicas 0
# 9,删除deployment
kubectl delete deploy nginx-deployment-demo
# 10,Terminating代表正在终结


Deployment命名规则/
Deployment Name: [Name]
ReplicaSet Name: [deployment-name]-[随机字符串]
Pod Name: [replicaset-name]-[随机字符串]


Deployment更新策略/
# 更新时,创建两个RS,其中旧的RS一次减少25%的Pod而新的RS一次创建25%的Pod
# 1,Deployment可以保证升级时只有一定数量的Pod是down的。默认的他会确保最多有一个Pod不可用
# 2,Deployment同时会创建超出期望数量的Pod,最多一个surge
# 3,随着k8s的版本升级,Deployment升级策略改变,由1-1转变为25%-25%
# 4,只要Deployment的rollout被触发,就会创建一个revision。当Deployment的Pod.template被更改,例如labels和容器镜像
# 5,扩容,缩容不会创建revision。意味着回退到历史revision时,只有Deployment中的Pod template部分回退
# 6,可以使用kubectl rollout status 查看Deployment的更改版本是否完成,rollout完成,kubectl rollout status将返回一个0值的code
# 7,通过.spec.revisionHistoryLimit来指定deployment最多保留多少revision历史记录,默认为10,设置为0就代表无法回退

DaemonSet

描述:如果需要在每台Node上运行同一个容器应用,可以采用k8s提供的DaemonSet控制器满足我们的需求,即DaemonSet,它类似于守护进程,可以在所有或者部分机器上运行同一个Pod

功能:1,当一个新节点加入到k8s集群中时DaemonSet创建的Pod将会被自动调度到该节点;2,当一个节点从k8s集群移除,DaemonSet创建的Pod也会被移除;3,如果删除DaemonSet,所有的与这个DaemonSet相关的Pod都会被删除

场景:1,在每个Node上运行集群存储Daemon,例如ceph,glusterd;2,在每个Node上运行日志收集daemon,例如fluentd,logstash;3,在每个Node上运行监控Daemon,例如Pormetheus,collectd,datadog,New Relic代理,或者Ganglia gmond


///DaemonSet示例
# DaemonSet控制器资源清单
# daemonset-example.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
    name: daemonset-example
    labels:
        app: daemonset
spec:
    selector:
        matchLabels:
            name: daemonset-example
    template:
        metadata:
            labels:
                name: daemonset-example
        spec:
            #tolerations:
            #    - key: node-role.kubernetes.io/master
            #      effect: NoShedule
            containers:
            - name: daemonset-example
              image: nginx:latest
              imagePullPolicy: IfNotPresent
              resources:
                limits:
                    cpu: 200m
                    memory: 200Mi
                requests:
                    cpu: 100m
                    memory: 100Mi
            terminationGracePeriodSeconds: 30

# 操作流程
# 1,部署
kubectl apply -f daemonset-example.yaml
# 2,查看
kubectl get ds -o wide
kubectl get pod -o wide --show-labels
# 3,验证daemonset的作用。我们将master节点的污点去除
kubectl describe node k8s-master-1 | grep "Taints"
# Taints: node-role.kubernetes.io/master:NoShedule
kubectl taint nodes k8s-master-1 node-role.kubernetes.io/master:NoShedule- # 去除污点
kubectl describe node k8s-master-1 | grep "Taints"
# Taints: <none>
# 4,检测去除污点后的DaemonSet
kubectl get ds -o wide # 此时daemonset已经将pod生成到master
kubectl get pod -o wide --show-labels # master节点上已经存在了Daemonset的Pod
# 5,再次向master节点增加污点
kubectl taint node k8s-master-1 node-role.kubernetes.io/master:NoShedule
# 此时daemonset管理的Pod只剩一个了
kubectl get ds
# 
kubectl get pod -o wide --show-labels # 此时运行在Master上的Pod已经是自助式Pod
# 删除后,由于已经不属于DaemonSet管理,所以不会再去管理
kubectl delete pod daemonset-example-xxx
# 6,删除daemonset控制器创建的Pod,--cascade=false不删除Pod
kubectl -cascade=true delete ds daemonset-example

Job

描述:Job控制器资源对象有自身的纠错能力,如果job运行的脚本没有以0状态码退出,Job将会重新执行直到至少有一个成功

///Job示例
# job-demo.yaml
apiVersion: batch/v1
kind: Job
metadata:
    name: job-demo-pi
spec:
    template:
        metadata:
            name: job-demo-pi
        spec:
            containers:
            - name: nginx-test
              image: nginx:latest
              command: ["/bin/sh", "-c", "date;echo Job Controller Demo!"]
              imagePullPolicy: IfNotPresent
            restartPolicy: Never

# 操作示例
# 1,创建Job-Pod
kubectl apply -f job-demo.yaml
# 2,查看
kubectl get jobs -o wide --show-labels
kubectl get pod -o wide --show-labels
# 3,结果
kubectl describe pod job-demo-pi-xxxx
# 4,删除Job资源
kubectl delete -f job-demo.yaml
kubectl delete jobs --all
kubectl get jobs
kubectl get pod

CronJob

描述:管理基于时间的Job,周期性的在给定时间点运行。

//特殊字段/
.spec
    template 格式类似Pod
    RestartPolicy Never/OnFailure,单个Pod时,Pod成功运行后Job结束
    completions Job结束需要运行的Pod个数,默认1个
    parallelism 标志并行运行的Pod的个数,默认1个
    activeDeadlineSeconds Pod重试最大时间,超过不会再重试
    schedule 调度周期 分时年月周
    jobTemplate Job模版,指定需要运行的任务,格式同job
    startingDeadlineSeconds 表示如果Job因为某种原因无法按调度准时启动,在spec.startingDeadlineSeconds时间段之内,CronJob仍然试图重新启动Job,如果在.spec.startingDeadlineSeconds时间之内没有启动成功,则不再试图重新启动。如果spec.startingDeadlineSeconds的值没有设置,则没有按时启动的任务不会被尝试重新启动。
    concurrencyPolicy:并发策略.“Allow” (允许,default):
“Forbid”(禁止): forbids;前个任务没执行完,要并发下一个的话,下一个会被跳过
“Replace”(替换): 新任务,替换当前运行的任务
    failedJobsHistoryLimit:记录失败数的上限,Defaults to 1.
    successfulJobsHistoryLimit: 记录成功任务的上限。 Defaults to 3.
#指定了 CronJob 应该保留多少个 completed 和 failed 的 Job 记录。将其设置为 0,则 CronJob 不会保留已经结束的 Job 的记录。
    suspend 暂停定时任务,对已经执行了的任务,不会生效; Defaults to false.


//CronJob示例/
# cronjob-demo.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
    name: cronjob-demo
spec:
    schedule: "*/1 * * * *"
    jobTemplate:
        spec:
            template:
                spec:
                    containers:
                    - name: cronjob-demo
                      image: nginx
                      args:
                      - /bin/sh
                      - -c
                      - date;echo Hello from the Kubernetes cluster,This is cronjob-demo;
                      imagePullPolicy: IfNotPresent
                    restartRolicy: OnFailure

# 操作流程
# 1,Help文档格式
kubectl explain CronJob.spec.jobTemplate.spec.template.spec.containers
# 2,创建
kubectl apply -f cronjob-demo.yaml
# 3,查看
kubectl get cj -o wide --show-labels
kubectl get jobs -o wide
kubectl get pod -o wide --show-labels
# 4,反馈结果
kubectl get pod | grep "cronjob" | cut -d " " -f1
# 5,删除cj
kubectl delete cronjob --all
kubectl delete -f cronjob-demo.yaml

    
    

StatefulSet

描述:有状态服务的应用程序

Q:有状态服务和无状态服务的区别?

A:服务所维护的与客户交互活动的信息称为状态信息。stateless Service,无状态服务,在应用程序运行过程中不保存任何数据和状态信息的服务;stateful Service,有状态服务,在应用程序运行过程中保存的数据或状态的服务

///特征///
1,稳定的网络标识,即Pod重新调度后其PodName和HostName不变,基于Headless Service来实现。
2,有序部署和有序扩展,基于init containers实现,在第n个Pod启动之前,前一个Pod必须处于Ready和Running状态
3,稳定的持久化存储,Pod重新调度后还是能访问到相同的持久化数据,基于PV/PVC,以及StorageClass实现
4,有序删除和停止,从N-1到0依次销毁


///启停顺序///
1,有序部署:部署stateful时,如果有多个Pod副本,会被顺序的创建
2,有序删除:当Pod被删除时,被终止的顺序是从N-1到0
3,有序扩展:扩展时,与部署一样,他前面的Pod必须都处于Running和Ready状态


///DNS域名格式///
1,stateful除了需要采用PV/PVC持久化Pod状态数据之外,还需要使用到Headless Service,该Service为StatefulSet控制的每个Pod创建一个DNS域名,格式为PodName.HeadlessServiceName


///Stateful Set示例///
# statefulset-demo.yaml
apiVersion: v1
kind: Service
metadata:
    name: nginx-statefulset-service
    labels:
        app: nginx
spec:
    clusterIP: None
    selector:
        app: nginx-sfs
    ports:
    - name: web
      port: 80
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
    name: web
spec:
    selector:
        matchLabels:
            app: nginx-sfs
    serviceName: "nginx-statefulset-service" # 与上面的Service名称要一致,是绑定的作用
    replicas: 3
    template:
        metadata:
            labels:
                app: nginx-sfs
        spec:
            containers:
            - name: nginx
              image: nginx:latest
              ports:
              - containerPort: 80
                name: web
              volumnMounts:
              - name www
                mountPath: /usr/share/nginx/html
    volumnClaimTemplates:
    - metadata:
        name: www
      spec: 
        accessModes: [ "ReadWriteOnce" ]
        storageClassName: "managed-nfs-storage"
        resources:
            requests:
                storage: 200Mi

# 操作流程
# 创建
kubectl apply -f statefulset-demo.yaml
# 查看StatrfulSet控制器,SVC,PVC
kubectl get sts,pvc -o wide | egrep "web"
kubectl get svc | grep "nginx-statefulset-service"
kubectl get ep -o wide | grep "nginx-statefulset-service"

Horizontal Pod Autoscaling

描述:自动扩展。它根据当前Pod资源的使用率,进行副本数的动态扩容和缩容,以便减轻pod的压力。当pod负载达到一定的阈值后,会根据扩缩容的策略生成更多新的Pod来分担压力,当Pod的使用比较空闲时,在稳定空闲一段时间后,还会自动减少Pod的副本数量


HPA的作用以及部署建议///
1,HPA的起始作用是Pod按照一定的策略进行自动扩容缩容,例如根据CPU利用率自动伸缩一个RC,Deploy,RS中管理的Pod副本数量;可以简单的理解为他不是控制器而是一个控制器的附属品,可以使用它去控制其他的控制器,从而使其他的控制器具有自动扩展的能力
2,如果要实现扩容缩容的功能,还需要部署heapster服务,用来收集和统计资源的利用率,支持kubectl top命令,heapster服务集成在prometheus MetricServer服务中
3,scale手动伸缩k8s资源对象的升级回滚扩容缩容,autoscale自动伸缩
4,k8s autoscale两种方式:水平扩展,实例数目的增减;垂直扩展,示例资源的增减,CPU或者内存



HPA实例///
# 1,构建测试的镜像,运行构建Deployment的HPA资源,名称为php-apache,并设置请求CPU的资源为200M,并暴露一个80端口
# hpa-demo.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
    name: php-apache-deployment
    labels:
        app: php-apache-deploy
spec:
    replicas: 1
    selector:
        matchLabels:
            app: nginx-apache
        matchExpressions:
        - key: app
          operator: In
          values: [php-apache]
    template:
        metadata:
            labels:
                app: php-apache
        spec:
            containers:
            - name: nginx
              image: nginx
              ports:
              - containerPort: 80
              resources:
                requests:
                    cpu: 128M
                    memory: 128Mi
                limits:
                    cpu: 200m
                    memory: 200Mi
              imagePullPolicy: IfNotPresent
---
kind: Service
apiVersion: v1
metadata:
    name: php-apache
spec:
    type: ClusterIP
    selector:
        app: php-apache
    ports:
    - protocol: TCP
      port: 80
      targetPort: 80

# 2,创建以及查看
kubectl apply -f hpa-demon.yaml
kubectl get deployment -o wide
kubectl get svc
kubectl get replicasets.apps -o wide

# 3,创建HPA控制器,当HPA控制的deployment资源对象的CPU使用率达到50%时,就进行扩容最多可以到10个
# 方式1
kubectl autoscale deployment php-apache-deployment --cpu-percent=50 --min=1 --max=10
# 方式2,资源清单模式,文件名:HorizontalPodAutoscaler.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
    name: php-apache-deployment
    namespace: default
spec:
    minReplicas: 1
    maxReplicas: 10
    scaleTargetRef:
        kind: Deployment
        name: php-apache-deployment
        apiVersion: apps/v1
    targetCPUUtilizationPercentage: 50
操作:kubectl apply -f HorizontalPodAutoscaler.yaml


# 4,模拟消耗php-apache的资源,并且验证Pod是否会自动扩容与缩容
# 使用压测工具ab
ab -c 5000 -n 2000000 http://host:port/


# 5,查看HPA的CPU占用情况和扩容缩容
watch -n 2 `kubectl get deployment | grep "php-apache-deployment" && kubectl get hpa && kubectl top pod -l app=php-apache`


# 6,停止死循环后,并不会立即减少Pod数量,会等一段时间后减少Pod数量,防止流量再次激增
watch -c -t -n 2 `kubectl get deployments | grep "php-apache-deployment" && kubectl get hpa && kubectl get pod -l app=php-apache`

# 7,删除
kubectl delete horizontalpodautoscalers.autoscaling php-apache-deployment


HPA Tips///
1,HPA只针对Deployment,RS,RC,StatefulSet创建的Pod资源

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值