摘要:


1、访问http://192.168.31.211:31103/kibana失败,但是其它IP(192.168.31.212等)可以,检查发现192.168.31.211的calico-node的READY:0/1,原因是kube-proxy没有运行:启动kube-proxy,删除重建Pod:calico-node后访问OK。

# k -n kube-system get pod -owide
NAME                READY   STATUS    RESTARTS      AGE     IP               NODE           NOMINATED NODE   READINESS GATES
calico-node-mq5s7   0/1     Running   0             2d      192.168.31.211   k8s-master01   <none>           <none>
# k -n kube-system describe pod calico-node-mq5s7
Events:
  Type     Reason     Age                    From     Message
  ----     ------     ----                   ----     -------
  Warning  Unhealthy  112s (x6754 over 16h)  kubelet  (combined from similar events): Readiness probe failed: 2022-12-14 04:19:39.700 [INFO][7961] confd/health.go 180: Number of node(s) with BGP peering established = 0
calico/node is not ready: BIRD is not ready: BGP not established with 192.168.31.212,192.168.31.213,192.168.31.214,192.168.31.215,192.168.31.216,192.168.31.217,192.168.31.218,192.168.31.219
  Warning  Unhealthy  5s  kubelet  Readiness probe failed: 2022-12-14 04:24:49.670 [INFO][9225] confd/health.go 180: Number of node(s) with BGP peering established = 0
calico/node is not ready: BIRD is not ready: BGP not established with 192.168.31.212,192.168.31.213,192.168.31.214,192.168.31.215,192.168.31.216,192.168.31.217,192.168.31.218,192.168.31.219
  Warning  Unhealthy  60s (x2 over 61s)  kubelet            Readiness probe failed: calico/node is not ready: BIRD is not ready: Error querying BIRD: unable to connect to BIRDv4 socket: dial unix /var/run/calico/bird.ctl: connect: connection refused
  Warning  Unhealthy  58s                kubelet            Readiness probe failed: 2022-12-14 04:29:24.274 [INFO][214] confd/health.go 180: Number of node(s) with BGP peering established = 0
calico/node is not ready: BIRD is not ready: BGP not established with 192.168.31.212,192.168.31.213,192.168.31.214,192.168.31.215,192.168.31.216,192.168.31.217,192.168.31.218,192.168.31.219
# systemctl start kube-proxy    //# systemctl enable kube-proxy
# k -n kube-system delete pod calico-node-mq5s7     //删除重建pod

2、runtime 是一个抽象的概念,字面意思是程序运行的时候。一般是指用来支持程序运行的实现。描述的是程序正常执行需要的支持:库、命令和环境等。常见的 runtime 为程序提供的支持:

  • 语言 runtime(C/Goang…):操作系统交互,垃圾回收,并发控制等
  • Java runtime: 虚拟机
  • 容器运行时:namespace,cgroup 等

容器运行时,就是容器运行起来需要的一系列程序和环境。比如如何使用 namespace 实现资源隔离,如何使用 cgroup 实现资源限制,这些都是容器运行时需要提供的实现。特征:

  • runtime 是在程序之外,不由程序编写者提供
  • runtime 的生命周期通常和程序生命周期关联

3、虚拟机访问K8s集群?

  • 虚拟机通常情况下无法直接访问 Kubernetes 集群中的 DNS 服务器以解析 Kubernetes 服务的Cluster IP的(虽然你也许可以通过一些黑客的手段做到)。
  • 虚拟机不需要访问 Cluster IP,直接对服务的 Endpoint 端点访问即可。

——容器DNS和主机名,以下三个文件在容器启动后被虚拟文件覆盖(init 层):

      /etc/hosts  /etc/resolv.conf  /etc/hostname

——Service网络:Service的就是在Pod之间起到服务代理的作用,对外表现为一个单一访问接口,将请求转发给Pod,Service的网络转发是Kubernetes实现服务编排的关键一环。Service都会生成一个虚拟IP,称为Service-IP, Kuberenetes Porxy组件负责实现Service-IP路由和转发,在容器覆盖网络之上又实现了虚拟转发网络。Kubernetes Porxy实现了以下功能:

  • 转发访问Service的Service-IP的请求到Endpoints(即Pod-IP)。
  • 监控Service和Endpoints的变化,实时刷新转发规则。
  • 负载均衡能力。

4、VirtualService 通过解耦客户端请求的目标地址和真实响应请求的目标工作负载为服务提供了合适的统一抽象层,而由此演化设计的配置模型为管理这方面提供了一致的环境。VirtualService 描述了用户可寻址目标到网格内实际工作负载之间的映射。可寻址的目标服务使用 hosts 字段(虚拟的目标地址)来指定,而网格内的实际负载由每个 route 配置项中的 destination 字段(必须是存在于 Istio 服务注册中心的实际目标地址)指定。

  • Gateway 用于管理进出网格的流量,指定可以进入或离开网格的流量。Gateway 配置应用于网格边缘的独立的 Envoy 代理上,而不是服务负载的 Envoy 代理上。为了为 Gateway 指定路由,需要通过 Virtual service 的 gateway 字段,将 Gateway 绑定到一个 Virtual service 上。
  • Istio 支持对接 Kubernetes、Consul 等多种不同的注册中心,控制平面 Pilot 启动时,会从指定的注册中心获取 Service Mesh 集群的服务信息和实例列表,并将这些信息进行处理和转换,然后通过 xDS 下发给对应的数据平面,保证服务之间可以互相发现并正常访问。同时,由于这些服务和实例信息都来源于服务网格内部,Istio 无法从注册中心直接获取网格外的服务,导致不利于网格内部与外部服务之间的通信和流量管理。为此,Istio 引入 ServiceEntry 实现对外通信和管理。使用 ServiceEntry 可以将外部的服务条目添加到 Istio 内部的服务注册表中,以便让网格中的服务能够访问并路由到这些手动指定的服务。ServiceEntry 描述了服务的属性(DNS 名称、VIP、端口、协议、端点)。

5、pod 和 node 通过 ptp 方式连接,即 pod 和 node 之间通过一个 veth pair 连接。(CNI

The ptp plugin creates a point-to-point link between a container and the host by using a veth device. One end of the veth pair is placed inside a container and the other end resides on the host. The host-local IPAM plugin can be used to allocate an IP address to the container. The traffic of the container interface will be routed through the interface of the host.

  • 宿主机创建docker0网桥, 通过veth pair 将容器和docker0连接:一旦一张虚拟网卡被“插”在网桥上,它就会变成该网桥的“从设备”。从设备会被“剥夺”调用网络协议栈处理数据包的资格,从而“降级”成为网桥上的一个端口。而这个端口唯一的作用,就是接收流入的数据包,然后把这些数据包的“生杀大权”(比如转发或者丢弃),全部交给对应的网桥
  • endpoint: 一个端点可以加入一个沙盒和一个网络, 端点实现: 如 veth pair, Open vSwitch内部端口等, 一个端点只能属于一个网络和沙盒
  • overlay: 使用VXLAN 方式, 需要配置额外存储, 如Consul, etcd或者zk等

6、Flannel是一个overlay网络,在已有的宿主机网络上,通过软件构建一个覆盖在已有宿主机网络之上的、可以把所有容器连通在一起的虚拟网络。(深入理解容器网络 - zhonghua | 钟华的博客 | zhongfox

  • UDP
  • VXLAN:Virtual Extensible LAN(虚拟可扩展局域网)
  • host-gw

1)UDP

  • 三层的 Overlay 网络
  • 各宿主机增加 Tunnel 设备 flannel0, flannel0 监听端口8285
  • 子网(Subnet): 在由 Flannel 管理的容器网络里,一台宿主机上的所有容器,都属于该宿主机被分配的一个“子网”, 子网与宿主机的对应关系,保存在 Etcd(从ectd中获得目的ip子网对应的宿主机ip,封装为UDP数据,把 UDP 包发往宿主机ip的 8285 端口
  • docker0 网桥的地址范围必须是 Flannel 为宿主机分配的子网: Docker Daemon 启动参数: 

2)VXLAN

  • VXLAN 本身就是 Linux 内核中的一个模块, 是 Linux 内核本身就支持的一种网络虚似化技术, VXLAN 可以完全在内核态实现上述封装和解封装的工作
  • 由内核 VXLAN 模块负责维护的二层网络,使得连接在这个 VXLAN 二层网络上的“主机”(虚拟机或者容器都可以)之间,可以像在同一个局域网(LAN)里那样自由通信
  • VTEP(VXLAN Tunnel EndPoint): 虚拟隧道端点, VXLAN 会在宿主机上设置一个特殊的网络设备作为“隧道”的两端, 它既有 IP 地址,也有MAC 地址
  • VXLAN Header VNI: VTEP 设备识别某个数据帧是不是应该归自己处理的重要标识。而在 Flannel 中,VNI 的默认值是 1,这也是为何,宿主机上的 VTEP 设备都叫作 flannel.1 的原因,这里的“1”,其实就是 VNI 的值
  • FDB (Forwarding Database):存储了node2.flannel.1.MAC 和 node2.IP 的映射关系:使用UDP发送VXLAN数据:
  1. 通过node1 上的FDB, 查询node2.flannel.1.MAC -> node2.IP
  2. 通过node常规ARPnode2.IP -> node2.MAC
  3. 生成外UDP包: [目的MAC:node2.MAC, 目的IP:node2.IP [VxlanHeader:VNI:1 [目的MAC:node2.flannel.1.MAC, 目的IP:container2.IP, ...]]]

3)host-gw

  • 必须要求集群宿主机之间是二层连通的
  • host-gw 其实就是将每个 Flannel 子网(Flannel Subnet,比如:10.244.1.0/24)的“下一跳”,设置成了该子网对应的宿主机的 IP 地址
  • Flannel 子网和主机的信息,都是保存在 Etcd 当中的。flanneld 只需要 WACTH 这些数据的变化,然后实时更新路由表即可

veth 连到了个网桥(network bridge)cni0 上。网桥工作在数据链路层(OSI 模型的第 2 层),连接多个网络(可多个网段)。当请求到达网桥,网桥会询问所有连接的接口(这里 pod 通过 veth 以网桥连接)是否拥有原始请求中的 IP 地址。如果有接口响应,网桥会将匹配信息(IP -> veth)记录,并将数据转发过去。当网桥询问哪个pod 拥有该IP但是没有得到回应,流程进入主机的路由寻址过程,到更高的集群层面。在集群层面有一张路由表,里面存储着每个节点的 Pod IP 网段(节点加入到集群时会分配一个 Pod 网段(Pod CIDR),比如在 k3s 中默认的 Pod CIDR 是 10.42.0.0/16,节点获取到的网段是10.42.0.0/24、10.42.1.0/24、10.42.2.0/24,依次类推)。通过节点的 Pod IP 网段可以判断出请求 IP 的节点,然后请求被发送到该节点。

7、tun/tap 的最主要应用场景,就是vpn ,tunnel,k8s应用就是节点间的tunnel. 

k8s Pod流量(kube-proxy)_IP

  • 使用Tun/Tap隧道绕过防火墙
  • 使用Tap隧道桥接两个远程站点