Zero to JupyterHub with Kubernetes中篇 - Kubernetes 常规使用记录

前言:纯个人记录使用。

  • 搭建 Zero to JupyterHub with Kubernetes 上篇 - Kubernetes 离线二进制部署。
  • 搭建 Zero to JupyterHub with Kubernetes 中篇 - Kubernetes 常规使用记录。
  • 搭建 Zero to JupyterHub with Kubernetes 下篇 - Jupyterhub on k8s。

参考: https://www.yuque.com/fairy-era/yg511q/xyqxge

文章目录

    • 1、Kubernets介绍
      • 1.1 简介
      • 1.2 架构与组件
    • 2、重要资源实战
      • 2.1 Namespace
      • 2.2 Pods
      • 2.3 Deployment
      • 2.4 pvc 和 pv 数据存储
      • 2.5 Service

1、Kubernets介绍

1.1 简介

Kubernetes是Google 团队发起的一个开源项目,用于自动部署、扩展和管理容器化(docker)的应用程序。主要目的是管理跨多个主机的容器。

Kubernetes 中的绝大多数概念都抽象成 Kubernetes 管理的一种资源对象(一切皆资源)。

1.2 架构与组件

在这里插入图片描述

Master : 负责管理集群,协调集群中的所有活动,例如调度应用程序、维护应用程序的所需状态、扩展应用程序和滚动更新。

  • kube-apiserver:集群控制的访问入口,提供HTTP REST服务。
  • kube-controller-manager:集群中所有资源对象的自动化控制中心,负责维护集群的状态,比如程序部署、故障检测、自动扩展、滚动更新等。
  • kube-scheduler:负责集群资源调度,按照策略将Pod调度到相应node上。
  • etcd:负责存储集群中各种资源对象信息(键值对形式)。

Node:k8s集群工作节点。每个工作节点都有一个kubelet,它管理本节点并且负责与Master主节点通信。每个节点上都需安装Docker相关服务。

  • kubelet :负责维护容器的生命周期,通过控制docker来创建、更新、销毁容器(负责Pod的创建、启动、监控、重启、销毁等工作),同时与Master 节点通讯,实现集群管理的基本功能。

  • kube-proxy:实现集群内部服务发现和负载均衡(代理应用的访问入口,如jupyterhub应用)。

  • docker:负责pod容器应用。

Kubernetes 核心组件

  • etcd:保存了整个集群的状态,就是一个数据库
  • apiserver :提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制
  • controller manager: 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等
  • scheduler :负责资源的调度、按照预定的调度策略将Pod调度到相应的机器上
  • kubelet :负责维护容器的生命周期、同时负责Volume(CSI/Container Storage Interface)和网络(CNI/Container Network Interface)的管理
  • kube-proxy :负责为Service提供cluster 内部的服务发现和负载均衡
  • docker:负责镜像管理以及Pod和容器的真正运行(CRI/Container R untime Interface)

其他插件:

  • Dashboard :提供集群GUI

  • Metrics-scraper: 为Dashboard提供资源监控

  • Ingress Controller :为服务提供外网接口

  • Coredns: 负责为整个集群提供DNS服务


2、重要资源实战

  • kubectl:k8s集群命令行工具

    kubectl [command] [type] [name] [flags]

    ● command:指定要对资源执行的操作,比如create、get、delete。
    ● type:指定资源的类型,比如deployment、pod、service。
    ● name:指定资源的名称,名称大小写敏感。
    ● flags:指定额外的可选参数。

    • command 资源操作命令

      # 基本命令
      create	创建一个资源
      edit	编辑一个资源
      get	    获取一个资源
      patch	更新一个资源
      delete	删除一个资源
      explain	解释展示资源文档
      
      # 运行调试命令
      run	        在集群中运行一个指定的镜像
      expose	    暴露资源为Service,常用于暴露应用端口
      describe	显示资源内部信息
      logs	    输出容器在Pod中的日志
      attach	    连接运行中的容器,通常用于与正在运行的进程进行交互,查看进程的输出或向进程发送输入。
      exec	    执行容器中的一个命令(bin/bash)  参数 -i(interactive)交互式 ,-t 启用伪终端
      cp	        在Pod内外复制文件
      rollout	    管理版本的发布
      scale	    扩(缩)容Pod的数量
      autoscale	自动调整Pod的数量
      
      # 高级命令
      apply	 通过yaml文件对资源进行配置
      label	 更新资源上的标签
      
      # 其他
      cluster-info	集群信息	显示集群信息
      version         显示当前Client和Server的版本
      api-resources   查看集群资源对象
      
    • type 资源操作类型

      # 查看集群所有资源对象
      [root@k8s-master ~/test]$ kubectl api-resources
      NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND
      namespaces                        ns           v1                                     false        Namespace
      pods                              po           v1                                     true         Pod
      nodes                             no           v1                                     false        Node
      # Pod资源控制器 
      replicasets                       rs           apps/v1                                true         ReplicaSet
      deployments                       deploy       apps/v1                                true         Deployment
      # 负载均衡和服务发现
      services                          svc          v1                                     true         Service
      ingresses                         ing          extensions/v1beta1                     true         Ingress
      # 资源存储
      persistentvolumeclaims            pvc          v1                                     true         PersistentVolumeClaim
      persistentvolumes                 pv           v1                                     false        PersistentVolume
       ...
      
  • 常规使用方式

    # 创建或更新资源
    kubectl apply -f xxx.yaml
    # 删除资源
    kubectl delete -f xxx.yaml
    # 查看资源
    kubectl get(describe) 资源名称
    

2.1 Namespace

  • Namespace:命名空间,用于进行资源隔离。

    • kubernetes系统中一种非常重要的资源,它的主要作用是用来实现多套系统的资源隔离或者多租户的资源隔离

    • 默认情况下,kubernetes集群中的所有Pod都是可以相互访问的。但是在实际中,可能不想让两个Pod之间进行互相的访问,那么此时就可以将两个Pod划分到不同的Namespace下。kubernetes通过将集群内部的资源分配到不同的Namespace中,可以形成逻辑上的“组”,以方便不同的组的资源进行隔离使用和管理。

    • 可以通过kubernetes的授权机制,将不同的Namespace交给不同租户进行管理,这样就实现了多租户的资源隔离。此时还能结合kubernetes的资源配额机制,限定不同租户能占用的资源,例如CPU使用量、内存使用量等等,来实现租户可用资源的管理。

    # 查看所有命名空间
    [root@k8s-master /data/s0/kubernetes/test]$ kubectl get namespace
    NAME                   STATUS   AGE
    default                Active   7d5h   # 所有未指定的Namespace的对象都会被分配在default命名空间。
    kube-node-lease        Active   7d5h   # 集群节点之间的心跳维护,v1.13开始引入。
    kube-public            Active   7d5h   # 此命名空间的资源可以被所有人访问(包括未认证用户)。
    kube-system            Active   7d5h   # 所有由kubernetes系统创建的资源都处于这个命名空间(calico网络pod)
    kubernetes-dashboard   Active   2d1h   # 人为自定义集群资源可视化命名空间
    # 查看命名空间中资源
    [root@k8s-master /data/s0/kubernetes/test]$ kubectl get pods -n kubernetes-dashboard -o wide(/json/yaml:结果输出形式) 
    NAME                                         READY   STATUS    RESTARTS   AGE   IP               NODE         NOMINATED NODE   READINESS GATES
    dashboard-metrics-scraper-7b59f7d4df-l6ngh   1/1     Running   0          28d   10.244.235.195   k8s-master   <none>           <none>
    kubernetes-dashboard-548f88599b-k7824        1/1     Running   1          28d   10.244.169.132   k8s-node2    <none>           <none>
    
    # 创建命名空间
    [root@k8s-master /data/s0/kubernetes/test]$ kubectl create ns test 
    namespace/test created
    
    

2.2 Pods

  • pods: Pod 是Kubernetes调度的基本单位,是一组紧密相关的容器集合(至少一个),它们共享PID、IPC、Network 和 namespace。Pod 设计理念是支持多个容器在一个Pod中共享网络和文件系统,可以通过进程间通讯和文件共享这种简单高效的方式组合完成整个服务。每个Pod可以由一个或多个业务容器和一个根容器(Pause)组成。一个Pod表示某个应用的一个实例。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • Pod 创建与删除

    • pod资源清单

      apiVersion: v1     #必选,版本号,例如v1
      kind: Pod         #必选,资源类型,例如 Pod
      metadata:         #必选,元数据
        name: string     #必选,Pod名称
        namespace: string  #Pod所属的命名空间,默认为"default"
        labels:           #自定义标签列表
           name: string                 
      spec:  #必选,Pod中容器的详细定义
        containers:  #必选,Pod中容器列表
          - name: string   #必选,容器名称
            image: string  #必选,容器的镜像名称
            imagePullPolicy: [ Always|IfNotPresent|Never]  #获取镜像的策略,always:总是从镜像仓库拉取;IfNotPresent:优先使用本地镜像,无再从镜像仓库拉取;Never 只使用本地镜像 
            command: [string]   #容器的启动命令列表,如不指定,使用打包时使用的启动命令
            args: [string]      #容器的启动命令参数列表
            workingDir: string  #容器的工作目录
            volumeMounts:       #挂载到容器内部的存储卷配置
              - name: string      #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
                mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
                readOnly: boolean #是否为只读模式
            ports: #需要暴露的端口库号列表
              - name: string        #端口的名称
                containerPort: int  #容器需要监听的端口号
                hostPort: int       #容器所在主机需要监听的端口号,默认与Container相同
                protocol: string    #端口协议,支持TCP和UDP,默认TCP
            env:   #容器运行前需设置的环境变量列表
              - name: string  #环境变量名称
                value: string #环境变量的值
            resources: #资源限制和请求的设置
              limits:  #资源限制的设置
                cpu: string     #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
                memory: string  #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
              requests: #资源请求的设置
                cpu: string    #Cpu请求,容器启动的初始可用数量
                memory: string #内存请求,容器启动的初始可用数量
            lifecycle: #生命周期钩子
      		postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
      		preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止
            livenessProbe:  #对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器
              exec:         #对Pod容器内检查方式设置为exec方式
                command: [string]  #exec方式需要制定的命令或脚本
              httpGet:       #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
                path: string
                port: number
                host: string
                scheme: string
                HttpHeaders:
                  - name: string
                    value: string
              tcpSocket:     #对Pod内个容器健康检查方式设置为tcpSocket方式
                port: number
                
                initialDelaySeconds: 0       #容器启动完成后首次探测的时间,单位为秒
                timeoutSeconds: 0          #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
                periodSeconds: 0           #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
                successThreshold: 0
                failureThreshold: 0
                securityContext:
                  privileged: false
        restartPolicy: [Always | Never | OnFailure]  #Pod的重启策略
        nodeName: <string> #设置NodeName表示将该Pod调度到指定到名称的node节点上
        nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上
        imagePullSecrets: #Pull镜像时使用的secret名称,以key:secretkey格式指定
          - name: string
        hostNetwork: false   #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
        volumes:   #在该pod上定义共享存储卷列表
          - name: string    #共享存储卷名称 (volumes类型有很多种)
            emptyDir: {}       #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
            hostPath:          #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
              path: string                #Pod所在宿主机的目录,将被用于同期中mount的目录
              type: DirectoryOrCreate     # 目录存在就使用,不存在就先创建再使用
            secret:          #类型为secret的存储卷,挂载集群与定义的secret对象到容器内部
              scretname: string  
              items:     
                - key: string
                  path: string
            configMap:         #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
              name: string
              items:
                - key: string
                  path: string
      
    • pod创建

      # 创建一个含 nginx:1.20 和busybox:1.30的pod
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl explain pod.spec.containers.volumeMounts # 可查看yaml配置文件相关参数
      [root@k8s-master /data/s0/kubernetes/test]$ vim pod_nginx_busybox.yaml
      apiVersion: v1
      kind: Pod
      metadata:
        name: pod-test     #   名字不要含下划线
        namespace: test
        labels:
          app: nginx
      spec:
        containers:
          - name: nginx
            image: nginx:1.20
            imagePullPolicy: IfNotPresent  # 优先使用本地镜像(注意P字母大小写)
            volumeMounts:                  # 将主机存储地址路径,挂载到容器对应目录
              - name: host-path      
                mountPath: /var/log/nginx  # 容器内路径  
          - name: busybox
            image: busybox:1.30
            imagePullPolicy: Never    # 只使用本地镜像
            command: ["/bin/sh","-c","touch /logs/log.txt;while true;do /bin/echo $(date +%T) >> /logs/log.txt;sleep 5;done;"]  # 容器启动后,每隔5秒,把日期写入日志文件
            volumeMounts:       
              - name: host-path      
                mountPath: /logs 
        volumes:              # 声明 主机存储路径(将容器内数据持久化在pod所在主机上)
          - name: host-path
            hostPath: 
              path: /data/s0/kubernetes/test/logs
              type: DirectoryOrCreate      # 如果目录不存在,就创建
      
      # 创建pod     
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl apply -f pod_nginx_busybox.yaml          
       pod/pod-nginx-busybox created
      
      # 查看pod     
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl get pods -n test -o wide 
       NAME                READY   STATUS    RESTARTS   AGE   IP               NODE         NOMINATED NODE   READINESS GATES
      pod-nginx-busybox   2/2     Running   0          73s   10.244.235.214   k8s-master   <none>           <none>
      
      # 查看服务
      [root@k8s-master /data/s0/kubernetes/test]$ curl 10.244.235.214:80
      <!DOCTYPE html>
      <html>
      <head>
      <title>Welcome to nginx!</title>
        ...
      <p><em>Thank you for using nginx.</em></p>
      </body>
      </html>
      
      # 查看容器外部挂载目录
      [root@k8s-master /data/s0/kubernetes/test]$ ls /data/s0/kubernetes/test/logs
      access.log  error.log  log.txt
      
      
    • pod删除

      # 删除pods
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl delete -f pod_nginx_busybox.yaml
      kubectl delete -f pod_nginx_busybox.yaml
      

2.3 Deployment

  • Deployment:kubernetes很少直接控制Pod,一般都是通过Pod控制器来完成的。Deployment是其中一种pod控制器。

    Deployment 控制器并不直接管理Pod,而是通过管理ReplicaSet来间接管理Pod,即:Deployment管理ReplicaSet,ReplicaSet管理Pod。

    Deployment 确保任意时间都有指定数量的pod 副本在运行。如果为某个Pod创建了Deployment 并且指定3个副本,它会创建3个Pod,并且持续监控它们。如果某个Pod不响应,那么Deploymen会替换它,保持总数为3,如果之前不响应的Pod恢复了,超出3个副本,Deployment 将终止其中一个保持总数为3。当创建Deployment 时,需要指定两个东西:

    ​ Pod模版:用来创建Pod副本的模版

    ​ Label标签:Deployment 需要监控的 Pod 的标签。(通过Label Selector控制相应label的pods)

    在这里插入图片描述

    • ReplicaSet(RS):作用是保证一定数量的Pod能够正常运行,它会持续监听这些Pod的运行状态,一旦Pod发生故障,就会重启或重建。同时它还支持对Pod数量的扩缩容。Deployment 控制器 在ReplicaSet控制器的基础上增加了版本更新或回退,应用发布的停止与继续。
  • **Label:**不是资源对象,是识别 Kubernetes资源对象的标签,以key:value的方式附加到对象上(key最长不能超过63字节,value可以为空,也可以是不超过253字节的字符串)。Label不提供唯一性,并且实际上经常很多对象(如pods对象)都是使用相同的label来标识具体的应用。 Label 定义好后其他对象可以使用Label Selector 来选择一组相同label的对象。

    • deployment 资源清单

      apiVersion: apps/v1 # 版本号 
      kind: Deployment # 类型 
      metadata: # 元数据 
        name: <string> # rs名称 
        namespace: <string> # 所属命名空间 
        labels: <map[string]string> #标签 
          controller: deploy 
      spec: # 详情描述 
        replicas: <integer> # 副本数量 
        revisionHistoryLimit: <integer> # 保留历史版本,默认为10 
        paused: false # 暂停部署,默认是false 
        progressDeadlineSeconds: <integer> # 部署超时时间(s),默认是600 
        strategy: # 策略 
          type: Recreate/RollingUpdate # 滚动更新策略,默认滚动更新
          rollingUpdate: # 滚动更新 
            maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数 
            maxUnavailable: 30% # 最大不可用状态的Pod 的最大值,可以为百分比,也可以为整数 
        selector: # 选择器,通过它指定该控制器管理哪些pod 
          matchLabels: <map[string]string> # Labels匹配规则 
            app: nginx-pod 
          matchExpressions: # Expressions匹配规则 
            key: <string> # app
            operator: <string> # In 
            values: [nginx-pod] 
        template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本 
          metadata:
            annotations:   <map[string]string> # 版本备注
              deployment.kubernetes.io/revision: "1"   # 定义版本号
              kubernetes.io/change-cause: "nginx:1.20"  # 版本注释说明
            labels: 
              app: nginx-pod 
          spec: 
            containers: 
              - name: nginx 
                image: nginx:1.21
                imagePullPolicy: IfNotPresent
                ports: 
                  - containerPort: 80
      
    • deployment 创建与使用

      # deployment yaml文件创建
      [root@k8s-master /data/s0/kubernetes/test]$ vim deploy-nginx.yaml
      apiVersion: apps/v1 
      kind: Deployment
      metadata: 
        name: deploy-nginx       # deploy 名称 
        namespace: test 
        labels: 
          controller: deploy 
      spec:
        replicas: 3              # 3个副本 
        revisionHistoryLimit: 3  
        paused: false
        progressDeadlineSeconds: 600 
        strategy:
          type: RollingUpdate 
          rollingUpdate: 
            maxSurge: 30% 
            maxUnavailable: 30%
        selector:
          matchLabels: 
            app: nginx-pod 
        template:               # pod 模板
          metadata:
            annotations:   
              deployment.kubernetes.io/revision: "1"  
              kubernetes.io/change-cause: "nginx:1.20"  
            labels: 
              app: nginx-pod 
          spec: 
            containers: 
              - name: nginx 
                image: nginx:1.20 
                imagePullPolicy: IfNotPresent
                ports: 
                  - containerPort: 80
                volumeMounts:                  
                  - name: host-path      
                    mountPath: /var/log/nginx
            volumes:             
              - name: host-path
                hostPath: 
                  path: /data/s0/kubernetes/test/logs1
                  type: DirectoryOrCreate     
                  
                  
      # deployment 生成
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl apply -f deploy-nginx.yaml
      deployment.apps/deploy-nginx created
      
      # deployment 查看
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl get deploy -n test
      NAME           READY   UP-TO-DATE   AVAILABLE   AGE
      deploy-nginx   3/3     3            3           46s
      # 查看 replicaset
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl get rs -n test -o wide
      NAME                      DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES       SELECTOR
      deploy-nginx-59b4f66f9c   3         3         3       3m18s   nginx        nginx:1.20   app=nginx-pod,pod-template-hash=59b4f66f9c
      # 查看 pod
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl get pod -n test -o wide
      NAME                            READY   STATUS    RESTARTS   AGE     IP               NODE         NOMINATED NODE   READINESS GATES
      deploy-nginx-59b4f66f9c-6jbv5   1/1     Running   0          4m20s   10.244.235.216   k8s-master   <none>           <none>
      deploy-nginx-59b4f66f9c-j8nzm   1/1     Running   0          4m20s   10.244.235.215   k8s-master   <none>           <none>
      deploy-nginx-59b4f66f9c-k7ng9   1/1     Running   0          4m20s   10.244.36.74     k8s-node1    <none>           <none>
      # 查看历史版本
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl rollout history deployment deploy-nginx -n test
      REVISION  CHANGE-CAUSE
      1         nginx:1.20
      
      
    • deployment 版本更新与回退

      # nginx 版本升级 
      [root@k8s-master /data/s0/kubernetes/test]$ vim deploy-nginx.yaml
      nginx:1.20 --> nginx:1.21
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl apply -f deploy-nginx.yaml 
      # 查看pod变化 - pod 分批滚动更新
      [root@k8s-node1 /data/s0/kubernetes/test]$ kubectl get rs -n test -w
      deploy-nginx-5f475b845c-2v4fj   1/1     Running   0          72s
      deploy-nginx-5f475b845c-895c9   1/1     Running   0          72s
      deploy-nginx-5f475b845c-zdgnz   1/1     Running   0          72s
      deploy-nginx-785b98f9c6-2dv65   0/1     Pending   0          0s
      deploy-nginx-785b98f9c6-2dv65   0/1     Pending   0          0s
      deploy-nginx-785b98f9c6-2dv65   0/1     ContainerCreating   0          0s
      deploy-nginx-785b98f9c6-2dv65   0/1     ContainerCreating   0          1s
      deploy-nginx-785b98f9c6-2dv65   1/1     Running             0          2s
      deploy-nginx-5f475b845c-895c9   1/1     Terminating         0          115s
      deploy-nginx-785b98f9c6-6hvdb   0/1     Pending             0          0s
      deploy-nginx-785b98f9c6-6hvdb   0/1     Pending             0          0s
      deploy-nginx-785b98f9c6-6hvdb   0/1     ContainerCreating   0          0s
      deploy-nginx-785b98f9c6-6hvdb   0/1     ContainerCreating   0          1s
      deploy-nginx-785b98f9c6-6hvdb   1/1     Running             0          2s
      deploy-nginx-5f475b845c-2v4fj   1/1     Terminating         0          117s
      deploy-nginx-785b98f9c6-bbstf   0/1     Pending             0          0s
      deploy-nginx-785b98f9c6-bbstf   0/1     Pending             0          0s
      deploy-nginx-785b98f9c6-bbstf   0/1     ContainerCreating   0          0s
      deploy-nginx-5f475b845c-895c9   0/1     Terminating         0          117s
      deploy-nginx-785b98f9c6-bbstf   0/1     ContainerCreating   0          1s
      deploy-nginx-785b98f9c6-bbstf   1/1     Running             0          1s
      deploy-nginx-5f475b845c-zdgnz   1/1     Terminating         0          118s
      deploy-nginx-5f475b845c-2v4fj   0/1     Terminating         0          119s
      deploy-nginx-5f475b845c-2v4fj   0/1     Terminating         0          2m
      deploy-nginx-5f475b845c-2v4fj   0/1     Terminating         0          2m
      deploy-nginx-5f475b845c-zdgnz   0/1     Terminating         0          2m
      deploy-nginx-5f475b845c-zdgnz   0/1     Terminating         0          2m2s
      deploy-nginx-5f475b845c-zdgnz   0/1     Terminating         0          2m2s
      deploy-nginx-5f475b845c-895c9   0/1     Terminating         0          2m3s
      deploy-nginx-5f475b845c-895c9   0/1     Terminating         0          2m3s
      # 查看历史版本
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl rollout history deployment deploy-nginx -n test
      REVISION  CHANGE-CAUSE
      1         nginx:1.20
      2         nginx:1.21
      
      
      # 版本回退
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl get rs -n test -o wide
      NAME                      DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES       SELECTOR
      deploy-nginx-5f475b845c   0         0         0       4m15s   nginx        nginx:1.20   app=nginx-pod,pod-template-hash=5f475b845c
      deploy-nginx-785b98f9c6   3         3         3       2m22s   nginx        nginx:1.21   app=nginx-pod,pod-template-hash=785b98f9c6
      
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl rollout undo deployment deploy-nginx --to-revision=1 -n test
      deployment.apps/deploy-nginx rolled back
      
      # 查看版本回退效果
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl get rs -n test -o wide
      NAME                      DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES       SELECTOR
      deploy-nginx-5f475b845c   3         3         3       17m   nginx        nginx:1.20   app=nginx-pod,pod-template-hash=5f475b845c
      deploy-nginx-785b98f9c6   0         0         0       15m   nginx        nginx:1.21   app=nginx-pod,pod-template-hash=785b98f9c6
      
      
    • deployment 清除

      [root@k8s-master /data/s0/kubernetes/test]$ kubectl delete -f deploy-nginx.yaml
      deployment.apps "deploy-nginx" deleted
      

2.4 pvc 和 pv 数据存储

​ 容器持久化存储采用hostPath方式(表示挂载Pod所在宿主机的目录),但使用pod控制器重启或更新pod时,Pod可能别的Node节点启动,这样pod读写文件就找不到之前对应node文件。

  • nfs服务器

    NFS是一个网络文件共享存储系统,可以搭建一台NFS服务器,然后将Pod中的存储直接连接到NFS系统上,这样,无论Pod在节点上怎么转移,只要Node和NFS的对接没有问题,数据就可以成功访问。

    在这里插入图片描述

    ## nfs 安装包下载
    # 联网环境下
    # > yum install -y nfs-utils rpcbind 
    # 离线安装(联网机器下载安装包,离线机器安装rpm)
    联网机器 > yum  reinstall  --downloadonly --downloaddir ./  rpcbind /nfs-utils
    离线机器 > rpm -ivh *.rpm
    
    # Nfs服务创建
    # 设置共享目录
    [root@k8s-node1 /data/s0/kubernetes/nfs]$ vim /etc/exports
    /data/s0/kubernetes/nfs 192.168.10.0/24(rw,no_root_squash) # 设置共享网段
    [root@k8s-node1 /data/s0/kubernetes/nfs]$ chmod 777 -R /data/s0/kubernetes/nfs
    # 加载配置
    [root@k8s-node1 /data/s0/kubernetes/nfs]$ exportfs -r
    # 服务启动
    [root@k8s-node1 /data/s0/kubernetes/nfs]$ systemctl start rpcbind
    [root@k8s-node1 /data/s0/kubernetes/nfs]$ systemctl start nfs
    
    # 其他需要存储的节点安装nfs-utils,目的可以驱动NFS设备
    # 在其他节点测试共享是否成功
    [root@k8s-master /data/s0/kubernetes]$ showmount -e k8s-node1
    [root@k8s-node2 /data/s0/kubernetes]$ showmount -e k8s-node1
    
    
  • PVC 和 PV 高级存储

    PVC(Persistent Volume Claim):持久化卷请求声明,是用户向k8s系统发出的一种存储资源申请。

    PV(Persistent Volume):持久化卷,是对底层的共享存储的一种抽象。

    目的:隔离应用方与存储方,做到应用程序与底层存储解耦。

    在这里插入图片描述

    • PV 与 PVC 资源清单

      # PV 资源清单
      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: pv1      # 注意pv无需指定命名空间
      spec:
        nfs: # 存储类型,和底层实际存储对应(NFS只是其中一种)
          path: <string>
          readOnly: false # 只读权限
          server: <string> -required
        capacity: <map[string]string> # 存储能力,目前只支持存储空间的设置
          storage: 2Gi
        accessModes: <[]string> # 访问模式
          - ReadWriteOnce # 读写权限,允许单个节点
          - ReadOnlyMany  # 只读权限,允许多个节点
          - ReadWriteMany # 读写权限,允许多个节点
        storageClassName: <string> # 存储类别,具有特定类型的PV只能和请求了该类别的PVC进行绑定
        persistentVolumeReclaimPolicy: <string> # 回收策略:Retain(保留)/Recycle(回收)/Delete(应用后端删除)
        
        
      # PVC 资源清单
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: pvc1
        namespace: test
      spec:
        accessModes: <[]string> # 访问模式
          - 
        selector: # 通过Label Selector的设置,可使PVC对于系统中已存在的PV进行筛选。
        storageClassName: # 存储类别
        resources: # 请求空间
          requests:
            storage: 5Gi
        
      
    • PV 与 PVC 创建使用

      • PV创建

        # PV 存储资源创建: 两个2G,一个3G
        # nfs 共享目录设置
        [root@k8s-node1 /data/s0/kubernetes/test]$ mkdir -pv /data/s0/kubernetes/nfs/{pv1,pv2,pv3,pv4,pv5}
        [root@k8s-node1 /data/s0/kubernetes/test]$ vim /etc/exports
        /data/s0/kubernetes/nfs/pv1  192.168.9.0/24(rw,no_root_squash)
        /data/s0/kubernetes/nfs/pv2  192.168.9.0/24(rw,no_root_squash)
        /data/s0/kubernetes/nfs/pv3  192.168.9.0/24(rw,no_root_squash)
        /data/s0/kubernetes/nfs/pv4  192.168.9.0/24(rw,no_root_squash)
        /data/s0/kubernetes/nfs/pv5  192.168.9.0/24(rw,no_root_squash)
        [root@k8s-node1 /data/s0/kubernetes/test]$ exportfs -r
        
        # pv创建
        [root@k8s-master /data/s0/kubernetes/test]$ vim pv.yaml
        apiVersion: v1
        kind: PersistentVolume
        metadata:
          name: pv1      
        spec:
          nfs: 
            path: /data/s0/kubernetes/nfs/pv1
            readOnly: false 
            server: k8s-node1
          capacity: 
            storage: 2Gi
          accessModes: 
            - ReadWriteMany 
          persistentVolumeReclaimPolicy: Retain
        ---
        apiVersion: v1
        kind: PersistentVolume
        metadata:
          name: pv2      
        spec:
          nfs: 
            path: /data/s0/kubernetes/nfs/pv2
            readOnly: false 
            server: k8s-node1
          capacity: 
            storage: 2Gi
          accessModes: 
            - ReadWriteMany 
          storageClassName: high
          persistentVolumeReclaimPolicy: Retain
        ---
        apiVersion: v1
        kind: PersistentVolume
        metadata:
          name: pv3      
        spec:
          nfs: 
            path: /data/s0/kubernetes/nfs/pv3
            readOnly: false 
            server: k8s-node1
          capacity: 
            storage: 3Gi
          accessModes: 
            - ReadWriteMany 
          storageClassName: high
          persistentVolumeReclaimPolicy: Retain 
          
        [root@k8s-master /data/s0/kubernetes/test]$ kubectl apply -f pv.yaml  
        persistentvolume/pv1 created
        persistentvolume/pv2 created
        persistentvolume/pv3 created
        # 查看pvs
        [root@k8s-master /data/s0/kubernetes/test]$ kubectl get pv 
        NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
        pv1    2Gi        RWX            Retain           Available                                   23s
        pv2    2Gi        RWX            Retain           Available           high                    23s
        pv3    3Gi        RWX            Retain           Available           high                    23s
        
      • PVC创建

        # PVC 应用资源请求
        [root@k8s-master /data/s0/kubernetes/test]$ vim pvc.yaml
        apiVersion: v1
        kind: PersistentVolumeClaim
        metadata:
          name: pvc1
          namespace: test
        spec:
          accessModes:
            - ReadWriteMany
          storageClassName: high
          resources: 
            requests:
              storage: 2Gi
        [root@k8s-master /data/s0/kubernetes/test]$ kubectl apply -f pvc.yaml 
        persistentvolumeclaim/pvc1 created
        # 查看pv存储卷,PVC在pvs中查找存储类型一致、且最低符合存储容量要求的pv进行绑定
        [root@k8s-master /data/s0/kubernetes/test]$ kubectl get pv
        NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM       STORAGECLASS   REASON   AGE
        pv1    2Gi        RWX            Retain           Available                                       3m58s
        pv2    2Gi        RWX            Retain           Bound       test/pvc1   high                    3m58s
        pv3    3Gi        RWX            Retain           Available               high                    3m58s
        
        
      • pod使用pvc

        # deployment - pod  持久化存储
        [root@k8s-master /data/s0/kubernetes/test]$ vim deploy-nginx.yaml
        apiVersion: apps/v1 
        kind: Deployment
        metadata: 
          name: deploy-nginx       # deploy 名称 
          namespace: test 
          labels: 
            controller: deploy 
        spec:
          replicas: 3              # 3个副本 
          revisionHistoryLimit: 3  
          paused: false
          progressDeadlineSeconds: 600 
          strategy:
            type: RollingUpdate 
            rollingUpdate: 
              maxSurge: 30% 
              maxUnavailable: 30%
          selector:
            matchLabels: 
              app: nginx-pod 
          template:               # pod 模板
            metadata:
              annotations:   
                deployment.kubernetes.io/revision: "1"  
                kubernetes.io/change-cause: "nginx:1.20"  
              labels: 
                app: nginx-pod 
            spec: 
              containers: 
                - name: nginx 
                  image: nginx:1.20 
                  imagePullPolicy: IfNotPresent
                  ports: 
                    - containerPort: 80
                  volumeMounts:                  
                    - name: nfs-path      
                      mountPath: /var/log/nginx
              volumes:             
                - name: nfs-path                      # 使用pvc(nfs)
                  persistentVolumeClaim: 
                    claimName: pvc1
                    readOnly: false
        [root@k8s-master /data/s0/kubernetes/test]$ kubectl apply -f deploy-nginx.yaml 
        # 查看pod
        [root@k8s-master /data/s0/kubernetes/test]$ kubectl get pod -n test -o wide
        NAME                           READY   STATUS    RESTARTS   AGE   IP               NODE         NOMINATED NODE   READINESS GATES
        deploy-nginx-6d8656f6d-2tzp2   1/1     Running   0          61s   10.244.36.80     k8s-node1    <none>           <none>
        deploy-nginx-6d8656f6d-p9zr9   1/1     Running   0          63s   10.244.235.222   k8s-master   <none>           <none>
        deploy-nginx-6d8656f6d-s7cfr   1/1     Running   0          59s   10.244.36.81     k8s-node1    <none>           <none>
        # 查看共享卷
        [root@k8s-node1 /data/s0/kubernetes]$ ls nfs/pv2
        access.log  error.log
        

2.5 Service

  • **Service:**可以看做是一组同类pod对外的唯一访问接口,也是通过Label Selector 来选择一组相同label的对象。借助Service,应用可以方便的实现服务发现和负载均衡。

    主要解决问题:

    • Pod的IP会随着Pod的重建产生变化,服务ip不固定。
    • Pod的IP仅仅是集群内部可见的虚拟的IP,外部无法访问,service可以暴露服务端口且能实现负载均衡。

    在这里插入图片描述

    • Service在很多情况下只是一个概念,真正起作用的其实是kube-proxy服务进程,每个Node节点上都运行了一个kube-proxy的服务进程。当创建Service的时候会通过API Server向etcd写入创建的Service的信息,而kube-proxy会基于监听的机制发现这种Service的变化,然后它会将最新的Service信息转换为对应的访问规则。

  • Service 创建与使用

    • Service 资源清单

      apiVersion: v1 # 版本
      kind: Service # 类型
      metadata: # 元数据
        name: <string>  # 资源名称
        namespace: <string> # 命名空间
      spec:
        selector: <map[string]string> # 标签选择器,用于确定当前Service代理那些Pod
          app: nginx
        type: <string> # Service的类型,指定Service的访问方式 ClusterIP/NodePort/LoadBalancer/ExternalName
        clusterIP: <string> # 虚拟服务的IP地址
        sessionAffinity: <string> # session亲和性,支持ClientIP、None两个选项,默认值为None
        ports: <[]Object> # 端口信息
          - port: 8080  # Service端口
            protocol: TCP # 协议
            targetPort : # Pod端口
            nodePort:  # 主机端口
      
    • Service 创建

      # 查看现有pod 
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl get pod -n test -o wide
      NAME                           READY   STATUS    RESTARTS   AGE   IP               NODE         NOMINATED NODE   READINESS GATES
      deploy-nginx-6d8656f6d-2tzp2   1/1     Running   0          55m   10.244.36.80     k8s-node1    <none>           <none>
      deploy-nginx-6d8656f6d-p9zr9   1/1     Running   0          55m   10.244.235.222   k8s-master   <none>           <none>
      deploy-nginx-6d8656f6d-s7cfr   1/1     Running   0          55m   10.244.36.81     k8s-node1    <none>           <none>
      
      # 配置Service
      [root@k8s-master /data/s0/kubernetes/test]$ vim nginx-svc.yaml
      apiVersion: v1 
      kind: Service 
      metadata: 
        name: svc  
        namespace: test 
      spec:
        selector: 
          app: nginx-pod
        type: NodePort
        ports:
          - port: 8080 
            protocol: TCP 
            targetPort: 80 
            nodePort: 30080  
      # 启动Service
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl apply -f nginx-svc.yaml  
      service/svc created
      # 查看服务
      [root@k8s-master /data/s0/kubernetes/test]$ kubectl get svc -n test -o wide
      NAME   TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE   SELECTOR
      svc    NodePort   10.0.0.240   <none>        8080:30080/TCP   52s   app=nginx-pod
      
      # 测试服务
      [root@k8s-master /data/s0/kubernetes/test]$ curl k8s-node1:30080
      <!DOCTYPE html>
      <html>
      <head>
      <title>Welcome to nginx!</title>
      ...
      <p>For online documentation and support please refer to
      <a href="http://nginx.org/">nginx.org</a>.<br/>
      Commercial support is available at
      <a href="http://nginx.com/">nginx.com</a>.</p>
      <p><em>Thank you for using nginx.</em></p>
      </body>
      </html>
                          
      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/924072.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

docker-compose搭建xxl-job、mysql

docker-compose搭建xxl-job、mysql 1、搭建docker以及docker-compose2、下载xxl-job需要数据库脚本3、创建文件夹以及docker-compose文件4、坑来了5、正确配置6、验证-运行成功 1、搭建docker以及docker-compose 略 2、下载xxl-job需要数据库脚本 下载地址&#xff1a;https…

HTTP有哪些风险?是怎么解决的?

一、风险 HTTP是通过明文传输的&#xff0c;存在窃听风险、篡改风险以及冒充风险。 二、如何解决 HTTPS在HTTP的下层加了一个SSL/TLS层&#xff0c;保证了安全&#xff0c;通过混合加密解决窃听风险、数字签名解决篡改风险、数字证书解决冒充风险。 &#xff08;1&#xff0…

《Django 5 By Example》阅读笔记:p339-p358

《Django 5 By Example》学习第13天&#xff0c;p359-p382总结&#xff0c;总计24页。 一、技术总结 1.session (1)session 存储方式 Database sessions File-based sessions Cached sessions Cached database sessions Cookie-based sessions (2)设置 CART_SESSION_I…

Python数据分析(OpenCV)

第一步通过pip安装依赖包&#xff0c;执行一下命令 pip install opencv-python 如果是Anaconda请在工具中自行下载 下载好咋们就可以在环境中使用了。 人脸识别的特征数据可以到 github上面下载&#xff0c;直接搜索OpenCV 然后我们在源码中通过cv2的级联分类器引入人脸的特征…

(免费送源码)计算机毕业设计原创定制:Java+ssm+JSP+Ajax SSM棕榈校园论坛的开发

摘要 随着计算机科学技术的高速发展,计算机成了人们日常生活的必需品&#xff0c;从而也带动了一系列与此相关产业&#xff0c;是人们的生活发生了翻天覆地的变化&#xff0c;而网络化的出现也在改变着人们传统的生活方式&#xff0c;包括工作&#xff0c;学习&#xff0c;社交…

工业AI质检 AI质检智能系统 尤劲恩(上海)信息科技有限公司

来的现代化工厂&#xff0c;将逐步被无人化车间取代&#xff0c;无人工厂除了产线自动化&#xff0c;其无人质检将是绕不开的话题。尤劲恩致力于帮助工业制造领域上下游工厂减员增效、提高品质效率&#xff0c;真正实现无人质检IQC/IPQC/OQC的在线质检系统。分析生产环节真实品…

C 语言数组与函数:核心要点深度剖析与高效编程秘籍

我的个人主页 我的专栏&#xff1a;C语言&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;点赞❤ 收藏❤ 目录 引言数组基础 2.1 数组的定义与初始化 2.2 一维数组的基本操作 2.3 二维数组及其应用 2.4 数组与指针的关系函数基础 3.1 函数的定义与调用 3.2…

XML JSON

XML 与 JSON 结构 XML&#xff08;eXtensible Markup Language&#xff09; 1. 定义 XML 是一种标记语言&#xff0c;用于描述数据的结构和内容。主要用于数据存储与交换。 2. 特点 可扩展性&#xff1a;用户可以自定义标签。层次化结构&#xff1a;数据以树形结构组织&…

蓝桥杯备赛笔记(一)

这里的笔记是关于蓝桥杯关键知识点的记录&#xff0c;有别于基础语法&#xff0c;很多内容只要求会用就行&#xff0c;无需深入掌握。 文章目录 前言一、编程基础1.1 C基础格式和版本选择1.2 输入输出cin和cout&#xff1a; 1.3 string以下是字符串的一些简介&#xff1a;字符串…

[代码随想录Day24打卡] 93.复原IP地址 78.子集 90.子集II

93.复原IP地址 一个合法的IP地址是什么样的&#xff1a; 有3个’.分割得到4个数&#xff0c;每个数第一个数不能是0&#xff0c;不能含有非法字符&#xff0c;不能大于255。 这个是否属于合法IP相当于一个分割问题&#xff0c;把一串字符串分割成4部分&#xff0c;分别判断每…

v-for产生 You may have an infinite update loop in a component render function

参考文章&#xff1a; 报错解析 [Vue warn]: You may have an infinite update loop in a component render function. 另外一个解决方法 例如: MyList 是一个数组&#xff0c;我希望将排序后的结果返回进行for循环&#xff0c;因此设计了一个myMethon函数 <div v-for"…

中国前首富胡志标亮相创客匠人盛会,点燃创始人 IP 新思维火花

创客匠人正式官宣&#xff01;原爱多VCD创始人、中国前首富胡志标受邀出席创客匠人5000人“全球创始人IP领袖高峰论坛”&#xff0c;将与我们携手共赴这场商业巅峰盛宴。 由创客匠人打造的“全球创始人IP领袖高峰论坛”将在2024年12月26日-28日在厦门市国际博览会议中心如期举…

qsort函数详解+代码展示

文章目录 概要系列文章目录前言(1) 定义(2) 使用&#xff08;举例子 上代码&#xff09;1、定义数组&#xff1a;2、定义比较函数&#xff1a;3、调用 qsort&#xff1a;4、输出结果&#xff1a; (3) 注意事项 小结 概要 本篇博客将详细地介绍qsort排序函数&#xff0c;&#x…

CSS之3D转换

三维坐标系 三维坐标系其实就是指立体空间&#xff0c;立体空间是由3个轴共同组成的。 x轴:水平向右注意:x右边是正值&#xff0c;左边是负值 y轴:垂直向下注意:y下面是正值&#xff0c;上面是负值 z轴:垂直屏幕注意:往外面是正值&#xff0c;往里面是负值 3D移动 translat…

2024年nvm保姆级安装教程

需求&#xff1a;当前我的nodejs的版本是6.14.10&#xff0c;想切换为更高的版本。故使用nvm工具来实现不同node版本之间的切换 目录 一、删除node二、nvm安装三、配置nvm镜像四、安装所需要的nodejs版本nvm常用命令 一、删除node 第一步&#xff1a;首先在控制面板删除node.j…

Python编程语言中的优雅艺术:数值分隔符的巧妙运用

在Python编程的世界里&#xff0c;有许多精巧的设计让代码更优雅、更易读。今天要分享的是一个看似简单却能大幅提升代码可读性的特性 —— 数值分隔符。这个特性从Python 3.6版本开始引入&#xff0c;它用一种极其优雅的方式解决了大数值表示的难题。 数值分隔符的本质与应用…

JS-06-事件监听

事件监听 当鼠标进行操作的时候能够对网页页面进行操作。 事件绑定 常见事件 onload: 当某个页面或者元素加载完成之后执行指定的代码块 onclick:鼠标单机的时候就执行指定的代码块 onblur\onfocus:鼠标点击的时候光标在的地方就是获得焦点否则失去焦点 onkeydown:绑定键盘…

Adaboost集成学习 | Python实现基于NuSVR-Adaboost多输入单输出回归预测

目录 效果一览基本介绍程序设计参考资料效果一览 基本介绍 基于NuSVR-Adaboost多输入单输出回归预测python代码 NuSVR是一种支持向量回归(SVR)算法的变体,用于解决回归问题。SVR是一种监督学习方法,它用于预测连续目标变量,而不是分类标签。NuSVR在SVR的基础上引入了一个…

数据结构C语言描述5(图文结合)--队列,数组、链式、优先队列的实现

前言 这个专栏将会用纯C实现常用的数据结构和简单的算法&#xff1b;有C基础即可跟着学习&#xff0c;代码均可运行&#xff1b;准备考研的也可跟着写&#xff0c;个人感觉&#xff0c;如果时间充裕&#xff0c;手写一遍比看书、刷题管用很多&#xff0c;这也是本人采用纯C语言…

ADS9-V2EBZ 评估板

ADS9-V2EBZ 评估板 概览 优势和特点 Xilinx Kintex Ultrascale XCKU15P-2FFVE1517E FPGA。 1 个 FMC 连接器。 20 个 28 Gbps 收发器&#xff0c;由一 (1) 个 FMC 连接器提供支持 HMC DRAM 简单 USB 3.0 端口接口。 随附两张微型 SD 卡&#xff0c;“TRX”用于 ADRV9026 评估…