美文网首页
8. K8s 资源部署

8. K8s 资源部署

作者: 一个反派人物 | 来源:发表于2021-11-30 15:25 被阅读0次

    1 Pod

    很少在 Kubernetes 中直接创建一个Pod,甚至是单实例(Singleton)的 Pod。 这是因为 Pod 被设计成了相对临时性的、用后即抛的一次性实体,不支持高可用。一般使用工作负载资源来创建和管理多个 Pod。 资源的控制器能够处理副本的管理、上线,并在 Pod 失效时提供自愈能力。
    能够管理一个或者多个 Pod 的工作负载资源有:

    • Deployment
    • ReplicaSet
    • DaemonSet
    • ReplicationController

    1.1 Pod中的内容

    Pod 类似于共享namesapce、cgroup、文件系统卷的一组 Docker 容器。创建Pod时,除了会创建1个或多个工作容器外,还会额外在Pod中创建Pod容器,Pod容器用于实现k8s的各种功能

    1.2 Pod模板

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: hello
    spec:
      template:
        # 这里是 Pod 模版
        spec:
          containers:
          - name: hello
            image: busybox
            command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
          restartPolicy: OnFailure
    

    1.3 Pod基本操作

    1.3.1 创建

    kubectl create 或 apply -f XXX.yaml
    

    1.3.2 查询

    查询基础信息

    kubectl get pods|pod名字
    kubectl get pods -o wide
    

    查询详细信息

    kubectl describe pod pod名字
    

    查询Pod的标签

    kubectl describe pod pod名字 --show-labels
    

    1.3.3 删除

    kubectl delete pod pod名字
    kubectl delete pod --all
    

    1.3.4 更新

    kubectl apply -f XXX.yaml
    

    2 ReplicationController

    ReplicationController 确保在任何时候都有特定数量的 Pod 副本处于运行状态。 换句话说,ReplicationController 确保一个 Pod 或一组同类的 Pod 总是可用的。
    RC会根据spec.selector将当前已经运行的Pod加入RC,当 Pod 数量过多时,ReplicationController 会终止多余的 Pod。当 Pod 数量太少时,ReplicationController 将会启动新的 Pod。

    ReplicationController在新版本中被ReplicaSet所取代,通常使用Deployment来部署ReplicaSet,而不是直接使用ReplicaSet。

    2.1 RC模板

    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: nginx
    spec:
      replicas: 3
      selector:
        app: nginx
      template:
        metadata:
          name: nginx
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx
            ports:
            - containerPort: 80
    
    #参数解释
    spec.replicas:               副本数
    spec.selector:               选择器,根据选择的条件筛选Pod的labels,将符合的Pod加入RC
    spec.template:               Pod的模板
    spec.template.metadata:      Pod的元数据
    spec.template.spec:          Pod的具体属性信息
    

    2.2 RC基本操作

    2.2.1 创建

    kubectl create 或 apply -f XXX.yaml
    

    2.2.2 查询

    查询基础信息

    kubectl get rc
    kubectl get rc -o wide
    

    查询详细信息

    kubectl describe rc rc名字
    

    2.2.3 删除

    kubectl delete rc rc名字
    kubectl delete rc --all
    

    2.2.4 调整副本数

    kubectl scale rc rc名字 --replicas=num
    

    3 Service

    3.1 Service概述

    问题:
    Pod创建完成后,如何访问Pod呢?直接访问Pod会有如下几个问题:

    • Pod会随时被Deployment这样的控制器删除重建,那访问Pod的结果就会变得不可预知。
    • Pod的IP地址是在Pod启动后才被分配,在启动前并不知道Pod的IP地址。
    • 应用往往都是由多个运行相同镜像的一组Pod组成,逐个访问Pod也变得不现实

    解决方法:
    Kubernetes中的Service对象就是用来解决上述Pod访问问题的。Service有一个固定IP地址Cluster IP,Service将访问它的流量转发给Pod,具体转发给哪些Pod通过Label来选择,而且Service可以给这些Pod做负载均衡。

    3.2 K8s中的3种IP地址

    3.2.1 Node IP

    Node物理节点的IP地址

    3.2.2 Cluster IP

    Service的IP地址,此为虚拟IP地址。外部网络无法ping通,只有kubernetes集群内部访问使用。

    • Cluster IP仅仅作用于Kubernetes Service这个对象,并由Kubernetes管理和分配P地址
    • Cluster IP无法被ping,他没有一个“实体网络对象”来响应
    • Cluster IP只能结合Service Port组成一个具体的通信端口,单独的Cluster IP不具备通信的基础,并且他们属于Kubernetes集群这样一个封闭的空间。
    • 在不同Service下的pod节点在集群间相互访问可以通过Cluster IP

    3.2.3 Pod IP

    每个Pod的IP地址

    • 同Service下的pod可以直接根据PodIP相互通信
    • 不同Service下的pod在集群间pod通信要借助于 cluster ip
    • pod和集群外通信,要借助于node ip

    3.2.4 3种IP的访问关系

    Cluster地址和pod地址在不同网段,Cluster地址为虚拟地址,不配在pod上或主机上,外部访问时,先到Node节点网络(所有Node开放同一个端口号),再转到service网络,最后代理给pod网络。


    3.3 Service的类型

    Service的类型决定了如何向外暴露Service

    3.3.1 ClusterIP


    通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是默认的 ServiceType。

    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: nginx
      name: nginx-clusterip
    spec:
      ports:
      - name: service0
        port: 8080                # 访问Service的端口
        protocol: TCP             # 访问Service的协议,支持TCP和UDP
        targetPort: 80            # Service访问目标容器的端口,此端口与容器中运行的应用强相关,如本例中nginx镜像默认使用80端口
      selector:                   # 标签选择器,Service通过标签选择Pod,将访问Service的流量转发给Pod,此处选择带有 app:nginx 标签的Pod
        app: nginx
      type: ClusterIP             # Service的类型,ClusterIP表示在集群内访问
      clusterIP: IP Address       # 指定Service使用的ClusterIP,默认为随机分配
    

    3.3.2 NodePort

    通过每个节点上的 IP 和静态端口(NodePort)暴露服务。 NodePort 服务会路由到自动创建的 ClusterIP 服务。 通过请求 <Node节点 IP>:<节点端口>,你可以从集群的外部访问一个 NodePort 服务。

    NodePort的端口范围默认是30000-32767,可以修改/etc/kubernetes/manifests/kube-apiserver.yaml文件从而修改端口范围。

    NodePort类型的Service例子:

    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
    spec:
      type: NodePort
      selector:
        app: MyApp
      ports:
        - port: 80
          targetPort: 80
          nodePort: 30007
    
    参数解释:
    spec.ports[*].port:                Cluster IP的端口
    spec.ports[*].targetPort:          Pod IP的端口
    spec.ports[*].nodePort:            Node IP的端口
    spec.selector:                     选择器,根据Pod的labels,将Pod加入到Service
    

    3.3.3 LoadBalancer

    3.3.4 ExternalName

    3.4 负载均衡模式

    Service默认的负载均衡模式是RR轮询模式,可以通过修改spec.sessionAffinityClientIP来实现源地址会话保持。可以设置会话保持的超时时间(默认时间是10800s),设置spec.sessionAffinityConfig.clientIP.timeoutSeconds 的值。

    apiVersion: v1
    kind: Service
    metadata:
      ...
    spec:
      ...
      sessionAffinity: ClientIP
      sessionAffinityConfig:
        clientIP:
          timeoutSeconds: 10
      type: NodePort
    

    4 Deployments

    4.1 Deployments概述

    Deployment 管理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能,

    • 创建 Deployment 以将 ReplicaSet 上线。 ReplicaSet 在后台创建 Pods。 检查 ReplicaSet 的上线状态,查看其是否成功。
    • 通过更新 Deployment 的 PodTemplateSpec,声明 Pod 的新状态。 新的 ReplicaSet 会被创建,Deployment 以受控速率将 Pod 从旧 ReplicaSet 迁移到新 ReplicaSet。 每个新的 ReplicaSet 都会更新 Deployment 的修订版本。
    • 如果 Deployment 的当前状态不稳定,回滚到较早的 Deployment 版本。 每次回滚都会更新 Deployment 的修订版本。
    • 扩大 Deployment 规模以承担更多负载。
    • 暂停 Deployment以应用对 PodTemplateSpec 所作的多项修改, 然后恢复其执行以启动新的上线版本。
    • 使用 Deployment 状态来判定上线过程是否出现停滞。
    • 清理较旧的不再需要的 ReplicaSet。

    4.2 Deployments模板

    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: nginx:1.14.2
            ports:
            - containerPort: 80
    
    #参数解释
    spec.replicas:               副本数
    spec.selector:               选择器,根据选择的条件筛选Pod的labels,将符合的Pod加入deployment
    spec.template:               Pod的模板
    spec.template.metadata:      Pod的元数据
    spec.template.spec:          Pod的具体属性信息
    

    4.3 Deployments创建流程

    首先根据文件创建deployment,加入--record参数来记录历史,方便在回滚时查看针对每个 Deployment 修订版本所执行过的命令。

    kubectl apply -f nginx/nginx-deployment.yaml --record
    

    Deployment会创建ReplicaSet,ReplicaSet负责启动Pods。ReplicaSet 的名称始终被格式化为[Deployment名称]-[随机字符串]。 其中的随机字符串是使用 pod-template-hash 作为种子随机生成的。

    Pod-template-hash 标签
    Deployment 控制器将 pod-template-hash 标签添加到 Deployment 所创建或收留的每个ReplicaSet 。
    此标签可确保 Deployment 的子 ReplicaSets 不重叠。 标签是通过对 ReplicaSet 的 PodTemplate 进行哈希处理。 所生成的哈希值被添加到 ReplicaSet 选择算符Pod 模板标签,并存在于在 ReplicaSet 可能拥有的任何现有 Pod 中。

    4.4 Deployments升级流程

    仅当 Deployment Pod 模板(即 .spec.template)发生改变时,例如模板的标签或容器镜像被更新, 才会触发 Deployment 上线。 其他更新(如对 Deployment 执行扩缩容的操作)不会触发上线动作。

    Deployment 控制器每次注意到新的 Deployment 时,都会创建一个 ReplicaSet 以启动所需的 Pods。 如果更新了 Deployment,则控制标签匹配 .spec.selector 但模板不匹配 .spec.template 的 Pods 的现有 ReplicaSet 被缩容。最终,新的 ReplicaSet 缩放为 .spec.replicas 个副本, 所有旧 ReplicaSets 缩放为 0 个副本。

    当 Deployment 正在上线时被更新,Deployment 会针对更新创建一个新的 ReplicaSet 并开始对其扩容,之前正在被扩容的 ReplicaSet 会被翻转,添加到旧 ReplicaSets 列表 并开始缩容。

    例如,假定你在创建一个 Deployment 以生成 nginx:1.14.2 的 5 个副本,但接下来 更新 Deployment 以创建 5 个 nginx:1.16.1 的副本,而此时只有 3 个nginx:1.14.2 副本已创建。在这种情况下,Deployment 会立即开始杀死 3 个 nginx:1.14.2 Pods, 并开始创建 nginx:1.16.1 Pods。它不会等待 nginx:1.14.2 的 5 个副本都创建完成 后才开始执行变更动作。

    升级操作,两种方式:

    1. 直接使用命令行更新镜像版本
    kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record
    
    1. 使用edit在线编辑
    kubectl edit deployment.v1.apps/nginx-deployment
    

    Deployment可以通过maxSurgemaxUnavailable两个参数控制升级过程中同时重新创建Pod的比例,这在很多时候是非常有用,配置如下所示。

    spec:
      strategy:
        rollingUpdate:
          maxSurge: 1
          maxUnavailable: 0
        type: RollingUpdate
    
    • maxSurge:与Deployment中spec.replicas相比,可以有多少个Pod存在,默认值是25%,比如spec.replicas为 4,那升级过程中就不能超过5个Pod存在,即按1个的步伐升级,实际升级过程中会换算成数字,且换算会向上取整。这个值也可以直接设置成数字。
    • maxUnavailable:与Deployment中spec.replicas相比,可以有多少个Pod失效,也就是删除的比例,默认值是25%,比如spec.replicas为4,那升级过程中就至少有3个Pod存在,即删除Pod的步伐是1。同样这个值也可以设置成数字。

    4.5 Deployments回滚流程

    Deployment之所以能如此容易的做到回滚,是因为Deployment是通过ReplicaSet控制Pod的,升级后之前ReplicaSet都一直存在,Deployment回滚做的就是使用之前的ReplicaSet再次把Pod创建出来。Deployment中保存ReplicaSet的数量可以使用revisionHistoryLimit参数限制,默认值为10。

    查看Deployment 修订历史

    kubectl rollout history deployment nginx-deployment
    

    输出

    deployment.apps/nginx-deployment
    REVISION  CHANGE-CAUSE
    1         kubectl apply --filename=nginx/nginx-deployment.yaml --record=true
    2         kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record=true
    

    查看第n次的修订历史

    kubectl rollout history deployment nginx-deployment --revision=n
    

    输出

    deployment.apps/nginx-deployment with revision #2
    Pod Template:
      Labels:   app=nginx
        pod-template-hash=559d658b74
      Annotations:  kubernetes.io/change-cause: kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record=true
      Containers:
       nginx:
        Image:  nginx:1.16.1
        Port:   80/TCP
        Host Port:  0/TCP
        Environment:    <none>
        Mounts: <none>
      Volumes:  <none>
    

    回滚到之前的修订版本

    kubectl rollout undo deployment nginx-deployment --to-revision=1
    

    回滚后,Deployment 修订历史发生变化,revision 1变为revision 3

    [root@centos7-wht ~]$ kubectl rollout history deployment nginx-deployment
    deployment.apps/nginx-deployment
    REVISION  CHANGE-CAUSE
    2         kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record=true
    3         kubectl apply --filename=nginx/nginx-deployment.yaml --record=true
    

    4.6 Deployments缩放

    kubectl scale deployment deployment名字 --replicas=个数
    

    4.7 暂停、恢复 Deployment

    可以在触发一个或多个更新之前暂停 Deployment,然后再恢复其执行。 这样做使得你能够在暂停和恢复执行之间应用多个修补程序,而不会触发不必要的上线操作。

    暂停

    kubectl rollout pause deployment nginx-deployment
    

    恢复

    kubectl rollout resume deployment nginx-deployment
    

    处于暂停状态的 Deployment不能回滚,除非先恢复其执行状态。

    4.8 Deployments进度监视

    kubectl rollout status deployment deploy名字
    

    5 Liveness Probe

    通过检测容器响应是否正常来决定是否重启Pod,Kubernetes支持如下三种探测机制:

    • HTTP GET:向容器发送HTTP GET请求,如果Probe收到2xx或3xx,说明容器是健康的。
    • TCP Socket:尝试与容器指定端口建立TCP连接,如果连接成功建立,说明容器是健康的。
    • Exec:Probe执行容器中的命令并检查命令退出的状态码,如果状态码为0则说明容器是健康的。

    Liveness Probe在containers字段中定义

    5.1 HTTP GET

    为Deployment中的Pod配置Liveness Probe,Probe往容器的80端口发送HTTP GET请求,如果请求不成功,Kubernetes会重启容器。

    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: nginx:1.14.2
            livenessProbe:           # liveness probe部分
              httpGet:               # HTTP GET定义
                path: /
                port: 80
            ports:
            - containerPort: 80
    

    5.2 TCP Socket

    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: nginx:1.14.2
            livenessProbe:           # liveness probe部分
              tcpSocket:
                port: 80
            ports:
            - containerPort: 80
    

    5.3 Exec

    在容器中执行cat /tmp/healthy命令,如果成功执行并返回0,则说明容器是健康的。

    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: nginx:1.14.2
            livenessProbe:           # liveness probe
              exec:                  # Exec定义
                command:
                - cat
                - /tmp/healthy
            ports:
            - containerPort: 80
    

    相关文章

      网友评论

          本文标题:8. K8s 资源部署

          本文链接:https://www.haomeiwen.com/subject/sjofaltx.html