美文网首页
[K8S系列四] K8S核心组件与核心概念(Pod、Deploy

[K8S系列四] K8S核心组件与核心概念(Pod、Deploy

作者: 925781609 | 来源:发表于2022-04-14 18:13 被阅读0次

    1. 核心组件与核心概念

    K8S集群分为Master节点和Node节点,Master节点负责调度分配任务,Node节点接受Master调度进行工作。

    1.1 Master节点组件

    1. API Server

    集群的统一入口,各组件协调者,以RESTful API方式提供接口服务,所有对象资源的增删查改和监听操作都交给API Server处理后再提交给Etcd存储。

    2. Controller Manager
    负责维护集群的状态,比如故障检测、自动扩展、滚动更新等。一个资源对应一个控制器,而Controller Manager就是负责管理这些控制器的。

    3. Scheduler
    负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上。

    4.etcd
    分布式键值存储系统,用于保存群集状态数据,比如Pod、Service等对象信息。

    1.2 Node组件

    1. kubelet
    kubelet是Master在Node节点上的Agent,管理本机运行容器的生命周期,比如创建容器、Pod挂载数据卷、下载secret、获取容器和节点状态等工作。kubelet将每个Pod转换成一组容器。

    2. kube-proxy
    责为Service提供cluster内部的服务发现和负载均衡。

    2. 核心概念

    2.1 Pod

    Pod是一个逻辑概念,是一组共享了某些资源的容器。Pod在K8S中是调度的最基本单位,以便容器互相依赖时,可以同时调度。
    Pod 里的所有容器,共享的是同一个 Network Namespace,并且可以声明共享同一个 Volume。每个Pod中都有一个Pause(Infra)容器,Pause容器是Kubernetes基础设施的一部分,Kubernetes管理的所有pod里,pause容器是第一个启动的,而其他用户定义的容器,则通过 Join Network Namespace 的方式,与 pause容器关联在一起。

    对于 Pod 里的容器 A 和容器 B 来说:

    • 它们可以直接使用 localhost 进行通信;
    • 它们看到的网络设备跟 Pause容器看到的完全一样;
    • 一个 Pod 只有一个 IP 地址,也就是这个 Pod 的 Network Namespace 对应的 IP 地址;
    • 当然,其他的所有网络资源,都是一个 Pod 一份,并且被该 Pod 中的所有容器共享;
    • Pod 的生命周期只跟 Infra 容器一致,而与容器 A 和 B 无关。
    image.png
    2.2 Controller

    1.ReplicaSet
    确保预期的Pod副本数量,很少直接使用,需要被Deployment管理。

    2.Deployment
    作用于一组Pod的创建和运行,控制pod应用的升级、回滚,当然也能控制pod的数量。

    3.Service
    在K8S中,一方面Pod有伸缩与重新部署的需求,Pod的IP大多数情况是不固定的,另一方面,同一组Pod之间也有负载均衡的需要。因此,一组Pod被抽象成一个Service统一向外暴露。Service与其后端Pod副本集群之间则是通过Label Selector实现关联。

    Service有以下三种类型:
    ClusterIP:提供一个集群内部的虚拟IP(clusterIP),以便在集群内部通过clutserIP:port访问;
    NodePort:在每个节点上打开一个端口,在集群外部可以通过nodeIP:nodePort访问,在内部依然可以通过clutserIP:port 访问;
    LoadBalancer:通过外部的负载均衡器来访问,多用于公有云上。

    ClusterIP NodePort

    Service vs Deployment

    • Service是从网络角度的抽象概念,类似于Nginx做负载均衡提供的统一网络入口;
    • Pod是最终的应用部署实体;
    • Deoplyment 负责创建和保持pod运行状态。

    3. 示例

    3.1 deployment
    #  whomai-deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: whoami-deployment
      labels:
        app: whoami
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: whoami
      template:
        metadata:
          labels:
            app: whoami
        spec:
          containers:
          - name: whoami
            image: jwilder/whoami
            ports:
            - containerPort: 8000
    
    # kubectl get pods -o wide
    whoami-deployment-8886867c8-67d4f   1/1     Running   0              45m   10.244.80.206   w2     <none>           <none>
    whoami-deployment-8886867c8-hgvmb   1/1     Running   0              45m   10.244.80.205   w2     <none>           <none>
    whoami-deployment-8886867c8-pc67z   1/1     Running   0              45m   10.244.190.88   w1     <none>           <none>
    
    # curl 10.244.80.206:8000
    I'm whoami-deployment-8886867c8-67d4f
    # curl 10.244.80.205:8000
    I'm whoami-deployment-8886867c8-hgvmb
    # curl 10.244.190.88:8000
    I'm whoami-deployment-8886867c8-pc67z
    
    3.2 Service

    1. ClusterIP
    whoami-clusterip.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: whoami-clusterip
    spec:
      type: ClusterIP
      selector:
        app: whoami
      ports:
        - protocol: TCP
          port: 8080 # 集群的8080端口
          targetPort: 8000 # Pod的8000端口
    
    # kubectl apply -f whoami-clusterip.yaml
    # kubectl get svc -o wide
    NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE   SELECTOR
    kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP    34d   <none>
    whoami-clusterip   ClusterIP   10.98.191.167   <none>        8080/TCP   8s    app=whoami
    
    # curl 10.98.191.167:8080
    I'm whoami-deployment-8886867c8-hgvmb
    # curl 10.98.191.167:8080
    I'm whoami-deployment-8886867c8-67d4f
    # curl 10.98.191.167:8080
    I'm whoami-deployment-8886867c8-67d4f
    # curl 10.98.191.167:8080
    I'm whoami-deployment-8886867c8-hgvmb
    # curl 10.98.191.167:8080
    I'm whoami-deployment-8886867c8-pc67z
    
    #  kubectl describe  svc whoami-clusterip
    Name:              whoami-clusterip
    Namespace:         default
    Labels:            <none>
    Annotations:       <none>
    Selector:          app=whoami
    Type:              ClusterIP
    IP Family Policy:  SingleStack
    IP Families:       IPv4
    IP:                10.98.191.167
    IPs:               10.98.191.167
    Port:              <unset>  8080/TCP
    TargetPort:        8000/TCP
    Endpoints:         10.244.190.88:8000,10.244.80.205:8000,10.244.80.206:8000
    Session Affinity:  None
    Events:            <none>
    
    

    这种Service在集群外部是无法访问的,因为它是基于每个集群节点上配置的iptables中的虚拟IP地址实现的,并没有真实的网络设备存在。 通过 iptables-save可以看到如下规则,这条 iptables 规则的含义是:凡是目的地址是 10.98.191.167、目的端口是 8080 的 IP 包,都应该跳转到另外一条名叫 KUBE-SVC-XYYCMFLZLJQGYLMQ 的 iptables 链进行处理。

    而我们前面已经看到,10.98.191.167正是这个 Service 的 VIP。所以这一条规则,就为这个 Service 设置了一个固定的入口地址。并且,由于 10.98.191.167只是一条 iptables 规则上的配置,并没有真正的网络设备,所以你 ping 这个地址,是不会有任何响应的。

    KUBE-SVC-XYYCMFLZLJQGYLMQ 它是一组规则的集合,如下所示,这三条链指向的最终目的地,其实就是这个 Service 代理的三个 Pod。所以这一组规则,就是 Service 实现负载均衡的位置。

    #  iptables-save
    -A KUBE-SERVICES -d 10.98.191.167/32 -p tcp -m comment --comment "default/whoami-clusterip cluster IP" -m tcp --dport 8080 -j KUBE-SVC-XYYCMFLZLJQGYLMQ
    -A KUBE-SVC-XYYCMFLZLJQGYLMQ -m comment --comment "default/whoami-clusterip" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-SZWRSKR7UEYM347Q
    -A KUBE-SVC-XYYCMFLZLJQGYLMQ -m comment --comment "default/whoami-clusterip" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-GXJY2AW3O6IJVNJZ
    -A KUBE-SVC-XYYCMFLZLJQGYLMQ -m comment --comment "default/whoami-clusterip" -j KUBE-SEP-3NPGKIHQFRDXBA2I
    

    2. NodePort
    whoami-nodeport.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: whoami-nodeport
    spec:
      type: NodePort
      selector:
        app: whoami
      ports:
        - protocol: TCP
          port: 8080. # service 端口
          targetPort: 8000 # Pod端口
          nodePort: 30000 # 可以指定对外暴露的随机端口。一般30000-32627之间的一个端口就可以
    
    # kubectl apply -f whoami-nodeport.yaml
    service/whoami-nodeport created
    # kubectl get svc -o wide
    NAME              TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE   SELECTOR
    whoami-nodeport   NodePort    10.111.44.34   <none>        8080:30000/TCP   8s    app=whoami
    
    

    通过lsof可以发现在物理机上开辟30000端口

    # lsof -i tcp:30000
    COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    kube-prox 3600 root   12u  IPv4 874479      0t0  TCP *:ndmps (LISTEN)
    

    在集群内通过clusterIP:port访问service

    # curl 10.111.44.34:8080
    I'm whoami-deployment-8886867c8-pc67z
    # curl 10.111.44.34:8080
    I'm whoami-deployment-8886867c8-67d4f
    # curl 10.111.44.34:8080
    I'm whoami-deployment-8886867c8-hgvmb
    

    在集群外通过nodeIP:nodePort 访问, nodeIP就是集群物理机的IP,这里是92.168.0.51、92.168.0.61、92.168.0.62。

    # curl 192.168.0.62:30000
    I'm whoami-deployment-8886867c8-hgvmb
    # curl 192.168.0.62:30000
    I'm whoami-deployment-8886867c8-67d4f
    # curl 192.168.0.62:30000
    I'm whoami-deployment-8886867c8-pc67z
    # curl 192.168.0.51:30000
    I'm whoami-deployment-8886867c8-pc67z
    # curl 192.168.0.51:30000
    I'm whoami-deployment-8886867c8-67d4f
    

    参考

    1. Kubernetes 架构
    2. K8S-概念-service-deployment
    3. k8s中Pod、ReplicaSet、Deployment、Service的概念
    4. 深入k8s:Pod对象中重要概念及用法
    5. k8s 中Service、DNS与服务发现
    6. Kubernetes的三种外部访问方式:NodePort、LoadBalancer 和 Ingress

    相关文章

      网友评论

          本文标题:[K8S系列四] K8S核心组件与核心概念(Pod、Deploy

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