• Kubernetes组件和网络架构介绍


    Kubernetes组件

    Kubernetes Master:kube-apiserver、kube-controller-manager、kube-scheduler
    Kubernetes Node:kube-proxy、kubelet

    kube-apiserver:  API-server 负载输出RESTful风格的Kubernetes API, 它是集群的所有REST操作命令的
    接入点,并负责接收、校验并响应所有REST请求,结果状态被持久存储于etcd中。
    因此API server 是整个集群网关

    kube-scheduler: 负责调度
    kube-controller-manager: 负责容器编排,集群内部的管理控制中心,负责集群内的Node、Pod副本、服务端点
    (Endpoint)、命名空间(Namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)的管理。

    kubelet:kubelet 是运行在node 上的守护进程,它从API server接收关于pod对象的配置信息并确保它们的
    处于期望状态(desired state目标状态)。kubelet会在API server上注册当前节点,定期向Master汇报节点
    资源使用情况,并通过cAdvisor监控容器和节点资源占用情况

    kube-proxy:一个网络代理,每个node上都运行一个kube-proxy守护进程,它能够按需为server资源对象生成
    iptables或ipvs规则,从而捕获访问当前server和GlusterIP 的流量并将其转发至后端正真pod对象

    CNI (Container Network Interface):eg:flannel、calico
    CRI (Container Runtime Interface):eg:docker
    CSI (Container Storage Interface):eg:PV
    OCI(Open Container Initiative, 开放容器标准):eg:runC

    pod:解析
    1.Pod是K8s进行创建、调度和管理的最小单位
    2.Pod运行于Node节点上, 若干相关容器的组合
    3.Pod内包含的容器运行在同一宿主机上,使用相同的网络命名空间、IP地址和端口,能够通过localhost进行通信
    4.Pod可以指定一组共享存储。Volumes Pod中的所有容器都可以访问共享卷,从而使这些容器可以共享数据
    5.Pod 就是 k8s 世界里的"应用",而一个应用可以由多个容器组成。

    ps:Pod本身无法自我修复,K8s中使用kube-controller-manager管理Pod
    pause容器:
     1)每个Pod中都有一个pause容器,pause容器做为Pod的网络接入点
     2)属于同一个Pod的所有容器共享网络的namespace
     3)一个Pod里的容器与另外主机上的Pod容器能够直接通信(lo)
     4)属于同一个Pod的所有容器共享Volume挂载卷

    一、K8s网络设计
    1.每个Pod都拥有一个独立IP地址,Pod内所有容器共享一个网络命名空间
    2.集群内所有Pod都在一个直接连通的扁平网络中,可通过IP直接访问
     (1) 所有容器之间无需NAT就可以直接互相访问
     (2) 所有Node和所有容器之间无需NAT就可以直接互相访问
     (3) 容器自己看到的IP跟其他容器看到的一样

    二、K8s网络要求
    K8s对网络的要求总的来讲主要有两个最基本的要求,分别是:
     1)要能够为每一个Node上的Pod分配互相不冲突的IP地址
     2)要所有Pod之间能够互相访问
     
    三、K8s网络规范
     CNI是由CoreOS提出的一个容器网络规范。已采纳规范的包括Apache Mesos, Cloud Foundry, Kubernetes, Kurma 和 rkt。
     另外 Contiv Networking, Project Calico 和 Weave这些项目也为CNI提供插件。
     
    四、K8s网络实现
    隧道方案
    隧道方案在IaaS层的网络中应用也比较多,将pod分布在一个大二层的网络规模下。网络拓扑简单,但随着节点规模的增长复杂度会提升。
    Weave:UDP广播,本机建立新的BR,通过PCAP互通
    Open vSwitch(OVS):基于VxLan和GRE协议,但是性能方面损失比较严重
    Flannel:UDP广播,VxLan
    Racher:IPsec

    路由方案
    路由方案一般是从3层或者2层实现隔离和跨主机容器互通的,出了问题也很容易排查。
    Calico:基于BGP协议的路由方案,支持很细致的ACL控制,对混合云亲和度比较高。
    Macvlan:从逻辑和Kernel层来看隔离性和性能最优的方案,基于二层隔离,所以需要二层路由器支持,大多数云服务商不支持,所以混合云上比较难以实现。

    五、K8s Pod的网络创建流程
    1.每个Pod除了创建时指定的容器外,都有一个kubelet启动时指定的基础容器
    2.kubelet创建基础容器,生成network namespace
    3.kubelet调用网络CNI driver,由它根据配置调用具体的CNI 插件(eg:calico,flannel)
    4.CNI 插件给基础容器配置网络
    5.Pod 中其他的容器共享使用基础容器的网络

    k8s网络

     

    三种 IP 定义
     1.Node IP:Node 节点的 IP 地址,即物理机(虚拟机)的 IP 地址。
     2.Pod IP:Pod 的 IP 地址,即 docker 容器的 IP 地址,此为虚拟 IP 地址。
     3.Cluster IP:Service 的 IP 地址,此为虚拟 IP 地址。

    三种 IP 的理解
      Node IP:是物理机的IP(或虚拟机IP)。每个Service都会在Node节点上开通一个端口,外部可以通过http://NodeIP:NodePort
      即可访问 Service 里的 Pod 提供的服务。
     
      Pod IP:是每个Pod的IP地址,Docker Engine根据 docker 网桥的 IP 地址段进行分配的,通常是一个虚拟的二层网络。
         同Service下的pod可以直接根据PodIP相互通信
         不同Service下的pod在集群间pod通信要借助于 cluster ip
         pod和集群外通信,要借助于node ip
         
      Cluster IP: 是Service的IP地址,此为虚拟 IP 地址,外部网络无法 ping 通,只有k8s集群内部访问使用。
         Cluster IP仅仅作用于K8s Service这个对象,并由K8es管理和分配P地址 Cluster
         IP无法被ping,他没有一个“实体网络对象”来响应 Cluster IP只能结合Service
         Port组成一个具体的通信端口,单独的Cluster IP不具备通信的基础,并且他们属于K8s集群这样一个封闭的空间。
         在不同Service下的pod节点在集群间相互访问可以通过Cluster IP 

    K8s的网络中pod的通信:
    1. 同一Pod内的容器间通信:
        因为pause容器提供pod内网络共享,所以容器直接可以使用localhost(lo)访问其他容器
        
    2. 各Pod彼此之间的通信(两个pod在一台主机上面, 两个pod分布在不同主机之上)
       1)两个pod在一台主机上面: 通过docker默认的docker网桥互连容器(docker0), ifconfig 查了docker0
       2)两个pod分布在不同主机之上: 通过CNI插件实现,eg: flannel、calico

    3. Pod与Service间的通信
       Service分配的ip叫cluster ip是一个虚拟ip(相对固定,除非删除service),这个ip只能在k8s集群内部使用,
       如果service需要对外提供,只能使用Nodeport方式映射到主机上,使用主机的ip和端口对外提供服务。
       节点上面有个kube-proxy进程,这个进程从master apiserver获取信息,感知service和endpoint的创建,然后做两个事:
        1.为每个service 在集群中每个节点上面创建一个随机端口,任何该端口上面的连接会代理到相应的pod
        2.集群中每个节点安装iptables/ipvs规则,用于clusterip + port路由到上一步定义的随机端口上面,所以集群中每个node上面都有service的转发规则:iptables -L -n -t filter

    Pod Network
    K8s的一个Pod中包含有多个容器,这些容器共享一个Network Namespace,即是共享一个Network Namespace中的一个IP。创建Pod时,首先会生成一个pause容器,然后其他容器会共享pause容器的网络。
    docker ps -a 可查看到/pause容器,和kubectl get pod -o wied 查到的容器名字是一样的

    pause的ip又是从哪里分配到的?如果还是用一个以docker0为网关的内网ip就会出现问题了。
    docker默认的网络是为同一台宿主机的docker容器通信设计的,K8s的Pod需要跨主机与其他Pod通信,
    所以需要设计一套让不同Node的Pod实现透明通信(without NAT)的机制。
    docker0的默认ip是172.17.0.1,docker启动的容器也默认被分配在172.17.0.1/16的网段里。跨主机的Pod
    通信要保证Pod的ip不能相同,所以还需要设计一套为Pod统一分配IP的机制。
    以上两点,就是K8s在Pod network这一层需要解决的问题,可以利用插件解决如:flannel或者calico

    喜欢请赞赏一下啦^_^

    微信赞赏

    支付宝赞赏

  • 相关阅读:
    python-flask-SQLAlchemy
    python-flask-script定制manage命令
    python-flask框架
    python-flask-wtforms
    python-思路整理-虚拟环境
    python--django-admin定制页面流程:
    友盟iOS微信登陆没有回调的原因
    用同一个工程创建两个不同版本的应用
    简单方法实现手势解锁
    iOS开发中地图开发的简单应用
  • 原文地址:https://www.cnblogs.com/lkj371/p/14525812.html
Copyright © 2020-2023  润新知