• Controller与Service系列(一) Controller基本概念


    一、简介

      控制器(Controller)是集群上管理和运行容器的对象。Pod就是通过Controller实现应用的运维,如伸缩、滚动升级等,其中Pod与Controller之间通过标签(Label)以及标签选择器(Selector)建立关联。

    控制器(Controller)对象有不同的类型,比较常用的有:

    • Deployment   使用它可以进行应用的部署、应用的升级回滚、弹性伸缩等。
    • StatefulSet  管理有状态应用,用来管理某 Pod集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符。
    • DaemonSet  确保全部(或者某些)节点上运行一个 Pod 的副本。
    • Job  一次性任务
    • CronJob 创建基于时隔重复调度的 Jobs

    二、Deployment   

    (一)应用部署

    Deployment常用的场景就是应用的部署、升级、回滚、伸缩等。

    1、部署准备

     在之前的操作中直接通过命令行的方式进行应用的部署:

    [root@k8smaster ~]# kubectl create development web --image=nginx

    但是这样不利于重用,所以可以采用yaml文件的方式:

    # 导出yaml文件
    [root@k8smaster ~]# kubectl create deployment web --image=nginx --dry-run -o yaml > web.yam

    可以看到yaml文件中的内容:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      creationTimestamp: null
      labels:
        app: web
      name: web
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: web
      strategy: {}
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: web
        spec:
          containers:
          - image: nginx
            name: nginx
            resources: {}
    status: {}

    可以看到Deployment控制器中的selector中与Pod中的labels进行匹配,它们之间就是基于此进行关联。

    2、yaml部署

    [root@k8smaster ~]# kubectl apply -f web.yaml 
    deployment.apps/web created

    目前该应用只能集群内部访问,需要暴露端口到外部,这样外部才能访问。

    3、应用发布(对外暴露端口)

    # 导出yaml文件
    [root@k8smaster ~]# kubectl expose deployment web --port=80 --type=NodePort --target-port=80 --name=webOut -o yaml > webOut.yaml
    apiVersion: v1
    kind: Service
    metadata:
      creationTimestamp: "2021-06-18T18:11:36Z"
      labels:
        app: web
      managedFields:
      - apiVersion: v1
        fieldsType: FieldsV1
        fieldsV1:
          f:metadata:
            f:labels:
              .: {}
              f:app: {}
          f:spec:
            f:externalTrafficPolicy: {}
            f:ports:
              .: {}
              k:{"port":80,"protocol":"TCP"}:
                .: {}
                f:port: {}
                f:protocol: {}
                f:targetPort: {}
            f:selector:
              .: {}
              f:app: {}
            f:sessionAffinity: {}
            f:type: {}
        manager: kubectl
        operation: Update
        time: "2021-06-18T18:11:36Z"
      name: web1
      namespace: default
      resourceVersion: "393318"
      selfLink: /api/v1/namespaces/default/services/web1
      uid: 9cbe6be0-d147-43a4-812f-32ae6722fdf3
    spec:
      clusterIP: 10.97.65.66
      externalTrafficPolicy: Cluster
      ports:
      - nodePort: 31681
        port: 80
        protocol: TCP
        targetPort: 80
      selector:
        app: web
      sessionAffinity: None
      type: NodePort
    status:
      loadBalancer: {}
    web1.yaml

    进行部署:

    [root@k8smaster ~]# kubectl apply -f web1.yaml 
    
    # 查看
    [root@k8smaster ~]# kubectl get pods,svc
    NAME                       READY   STATUS    RESTARTS   AGE
    pod/web-5dcb957ccc-j2pg4   1/1     Running   0          15m
    
    NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
    service/kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        61d
    service/web1         NodePort    10.97.65.66   <none>        80:31681/TCP   3m51s

    (二)应用升级、回滚

    1、应用升级

    # 升级
    [root@k8smaster ~]# kubectl set image deployment web nginx=nginx:1.15
    deployment.apps/web image updated
    
    # 查看升级状态
    [root@k8smaster ~]# kubectl rollout status deployment web
    deployment "web" successfully rolled out

    2、应用回滚

    # 查看回滚版本
    [root@k8smaster ~]# kubectl rollout history deployment web
    deployment.apps/web 
    REVISION  CHANGE-CAUSE
    1         <none>
    2         <none>
    
    # 回滚到上一个版本
    [root@k8smaster ~]# kubectl rollout undo deployment web
    deployment.apps/web rolled back
    
    # 回滚到指定版本
    [root@k8smaster ~]# kubectl rollout undo deployment web --to-revision=2

    (三)弹性伸缩

    # 伸缩前查看
    [root@k8smaster ~]# kubectl get pods,svc
    NAME                       READY   STATUS    RESTARTS   AGE
    pod/web-5dcb957ccc-66txn   1/1     Running   0          3m5s
    
    NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
    service/kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        61d
    service/web1         NodePort    10.97.65.66   <none>        80:31681/TCP   40m
    
    # 进行伸缩
    [root@k8smaster ~]# kubectl scale deployment web --replicas=3
    deployment.apps/web scaled
    
    # 伸缩后查看
    [root@k8smaster ~]# kubectl get pods,svc
    NAME                       READY   STATUS              RESTARTS   AGE
    pod/web-5dcb957ccc-66txn   1/1     Running             0          3m41s
    pod/web-5dcb957ccc-jx4kl   0/1     ContainerCreating   0          2s
    pod/web-5dcb957ccc-zvmcm   0/1     ContainerCreating   0          2s
    
    NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
    service/kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP        61d
    service/web1         NodePort    10.97.65.66   <none>        80:31681/TCP   41m

    三、StatefulSet  

      StatefulSet 用来管理某 Pod 集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符。所以相对于Deployment而言它是有状态的,需要考虑下面的情况:

    • 保持每个Pod独立、启动顺序、唯一性
    • 唯一的网络标识、持久存储

    创建StatefulSet:

    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: nginx-statefulset
      namespace: default
    spec:
      serviceName: nginx
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:latest
            ports:
            - containerPort: 80

      它创建了一个 Headless Service nginx用来发布 StatefulSet web中的 Pod 的 IP 地址,表现形式就是clusterIP为None。执行上面的yaml文件:

    [root@k8smaster ~]# kubectl apply -f statefulset.yaml 
    service/nginx created

    上面创建两个Pod的副本,但是它是按照{0,N-1}的顺序来创建Pod的,也就是Pod是有顺序的。

    其次查看创建的两个Pod:

    [root@k8smaster ~]# kubectl get pods
    NAME                  READY   STATUS    RESTARTS   AGE
    nginx-statefulset-0   1/1     Running   0          15m
    nginx-statefulset-1   1/1     Running   0          14m

    每个都是有唯一的名称,最后看一下网络标识,每个 Pod 都拥有一个基于其顺序索引的稳定的主机名。使用kubectl exec在每个 Pod 中执行hostname。

    [root@k8smaster ~]# for i in 0 1; do kubectl exec "nginx-statefulset-$i" -- sh -c 'hostname'; done
    nginx-statefulset-0
    nginx-statefulset-1

    四、DaemonSet  

    DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod

    DaemonSet 的一些应用场景:

    • 在每个节点上运行集群守护进程
    • 在每个节点上运行日志收集守护进程
    • 在每个节点上运行监控守护进程

    创建 一个日志收集工具的DaemonSet:

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: ds-test 
      labels:
        app: filebeat
    spec:
      selector:
        matchLabels:
          app: filebeat
      template:
        metadata:
          labels:
            app: filebeat
        spec:
          containers:
          - name: logs
            image: nginx
            ports:
            - containerPort: 80
            volumeMounts:
            - name: varlog
              mountPath: /tmp/log
          volumes:
          - name: varlog
            hostPath:
              path: /var/log

    执行该yaml文件:

    [root@k8smaster ~]# kubectl apply -f ds.yaml 
    daemonset.apps/ds-test created

    可以看到在各个node节点上已经部署了Pod:

    [root@k8smaster ~]# kubectl get pods -o wide
    NAME            READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
    ds-test-6qdwg   1/1     Running   0          84s   10.244.1.23   k8snode1   <none>           <none>
    ds-test-m79px   1/1     Running   0          84s   10.244.2.20   k8snode2   <none>           <none>

    进入到某个Pod中进行查看:

    [root@k8smaster ~]# kubectl exec -it ds-test-6qdwg bash
    kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
    root@ds-test-6qdwg:/# ls /tmp/log/
    anaconda  btmp-20210617  dmesg        maillog           pods    secure-20210617     tuned
    audit      containers     dmesg.old  maillog-20210617   ppp     spooler         vmware-vmsvc.log
    boot.log  cron         firewalld  messages           rhsm    spooler-20210617  wtmp
    btmp      cron-20210617  lastlog    messages-20210617  secure  tallylog         yum.log

    五、Job  

      Job 会创建一个或者多个 Pods,并将继续重试 Pods 的执行,直到指定数量的 Pods 成功终止。 随着 Pods 成功结束,Job 跟踪记录成功完成的 Pods 个数。 当数量达到指定的成功个数阈值时,任务(即 Job)结束。 删除 Job 的操作会清除所创建的全部 Pods。 挂起 Job 的操作会删除 Job 的所有活跃 Pod,直到 Job 被再次恢复执行。

    下面是一个 Job 配置示例。它负责计算 π 到小数点后 2000 位,并将结果打印出来。

    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

    执行:

    [root@k8smaster ~]# kubectl apply -f job.yaml 
    job.batch/pi created

    查看Pod状态:

    # 因为是一次性任务,所以执行后即结束
    [root@k8smaster ~]# kubectl get pods
    NAME            READY   STATUS      RESTARTS   AGE
    pi-vbmwk        0/1     Completed   0          4m26s

    查看结果:

    [root@k8smaster ~]# kubectl logs pi-vbmwk 
    3.14159265358979323846264338327950...

    六、CronJob 

    CronJobs 对于创建周期性的、反复重复的任务很有用,例如执行数据备份或者发送邮件。 CronJobs 也可以用来计划在指定时间来执行的独立任务,例如计划当集群看起来很空闲时 执行某个 Job。如下实例:

    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

    执行:

    [root@k8smaster ~]# kubectl apply -f cronjob.yaml 
    cronjob.batch/hello created

    可以看到周期性的调用:

    [root@k8smaster ~]# kubectl get pods
    NAME                     READY   STATUS              RESTARTS   AGE
    hello-1624090140-w8xcn   0/1     Completed           0          2m57s
    hello-1624090200-m2lng   0/1     ContainerCreating   0          2m21s
    hello-1624090260-bwhjj   0/1     ContainerCreating   0          80s
    hello-1624090320-bcd7b   0/1     ContainerCreating   0          20s

    查看某个Pod里面的内容:

    [root@k8smaster ~]# kubectl logs hello-1624090140-w8xcn
    Sat Jun 19 08:11:44 UTC 2021
    Hello from the Kubernetes cluster
    作者:iveBoy
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Android开发之实现多次点击事件
    Android Studio之导出JavaDoc出现编码GBK的不可映射字符
    java.lang.RuntimeException: Unable to get provider cn.jpush.android.service.DataProvider
    线程池 多线程运行结束后 如何关闭? ExecutorService的正确关闭方法
    Mac 系统安装 oh my zsh
    PHP 批量获取指定目录下的文件列表(递归,穿透所有子目录)
    HP中spl_autoload_register函数的用法
    PHPUnit-附录 C. XML 配置文件
    PHPUnit-附录 B. 标注
    PHPUnit-附录 A. 断言 (assert)
  • 原文地址:https://www.cnblogs.com/shenjianping/p/14901035.html
Copyright © 2020-2023  润新知