• k8s与云服务器之间服务互访之节点网络打通


    一、概述

    k8s暴露服务的方式有很多使用ingress、nodeport等,这类比较适用于无状态的服务,对于statefulset部署的有状态的服务,(关于statefulset的介绍参考kubernetes的官网或参考我的https://www.cnblogs.com/cuishuai/p/10243291.html),由于statefulset使用的是headless service。是固定网络标示的,也就是服务的完整域名是不会改变的。但是有两个问题:

          1、物理机在k8s集群的外面没办法解析k8s集群内部的域名

          2、解析域名后网络不能通信

    二、物理网络与k8s集群打通

    有了上面提出的两个问题,我们先来简单分析一下k8s的网络,我们使用的是calico-bgp+ipvs,所以这里就以calico为例,calico为k8s提供了一个网络空间,提供的地址池和k8s初始化时指定的pod-cidr是相同的。部署服务的时候会在地址池里面为pod分配地址,比如设置的是192.168.0.0/16,首先是分配node节点,一般情况下calico会先给node节点随机分配一个网段,例如有个节点是node1 ,calico会分配一个192.168.19.0网段,具体的子网掩码(netmask)要看路由表在任意节点上执行(route -n)查看。

    查看具体的分配,部署calico的时候选择的是将数据存储到etcd集群,所以也可以去etcd里面产看:

    # etcdctl get --prefix "/calico" --keys-only | grep "ipam/v2/host"

    /calico/ipam/v2/host/ku13-1/ipv4/block/192.244.190.128-26 /calico/ipam/v2/host/ku13-1/ipv4/block/192.244.190.192-26 /calico/ipam/v2/host/ku13-2/ipv4/block/192.244.32.0-26 /calico/ipam/v2/host/ku13-2/ipv4/block/192.244.32.64-26 /calico/ipam/v2/host/ku13-3/ipv4/block/192.244.6.192-26 /calico/ipam/v2/host/ku13-3/ipv4/block/192.244.7.0-26 /calico/ipam/v2/host/ku13-3/ipv4/block/192.244.7.64-26 /calico/ipam/v2/host/ku13-4/ipv4/block/192.244.70.0-26

    还有一个服务kube-proxy,这个服务负责node之间的网络通信,刷新ipvs列表。具体的calico和kube-proxy工作详情这里不做详解。

     

    我们了解到要想解决我们上面提出的两个问题,我们需要将kubernets里面的coredns服务拿出来,为物理机提供dns解析、然后需要将物理机与k8s集群网络打通。接下来我们解决这两个问题:

     

    解决第一个问题也需要以第二个问题为前提,所以我们只需要解决了第二个问题,第一个问题只需要在物理机上面的/etc/resolv.conf添加一条nameserver记录。

    解决第二个问题:网络打通

    打通网络我们需要两个工具:calico、kube-proxy

    我们之前的集群都是使用kubeadm部署的,所以我们可以很简单实现这两个服务的部署,如果不是使用kubeadm部署的集群可以参考网上这个服务的部署,本文不做介绍。主要介绍kubeadm部署的实现。

     

    我们准备一个服务器,上面需要部署kubeadm、docker具体的准备参考之前的集群初始化,我们将新服务器以node节点的形式加入到集群里面,使用kubeadm join很方便的将服务器加入到现有的k8s集群里面,这个服务器只需要分配很小的资源,因为这个上面不会部署任何服务,只有kubeadm join时部署的calico-node、kube-proxy。

    添加节点参考:https://www.cnblogs.com/cuishuai/p/9897006.html

    节点成功加入集群后还要执行一个操作,就是设置节点不能被调度:

    kubctl  drain  [node-name]  --ignore-daemonsets

     

    这样我们新加入的这个节点上面只部署了calico-node、kube-proxy,并且该服务器节点是能和k8s集群通信的,我们把该节点作为k8s网络与物理网络的gateway,所有物理服务器进入k8s集群网络的路由都经过这个gateway。这样就实现了通讯。

     

    2、生成路由规则

    在上面新部署的服务器上面有到k8s集群的所有路由,我们将这些路由进行提取生成一个路由表给物理机使用,将所有路由设置成默认路由,都经过上面新加服务器的ip。

    为了方便使用我写了一个生成脚本,此脚本在gateway节点即上面新加的节点上面执行:

    #cat generate-rule

    #!/bin/bash
    
    route -n | grep UG | grep -v ^0 | awk '{print $1,$3}' >a.txt
    
    ip=`ip a | grep eth0 | grep inet |awk -F '/' '{print $1}'|awk '{print $2}'`

    service_net="192.96.0.0"
    service_mask="255.255.0.0" #判断route.rule文件是否存在
    if [ -f route.rule ];then >route.rule fi
    #生成route.rule文件
    #添加coredns的路由
    echo "route add -net $service_net netmask $service_mask gw $ip" >route.rule
    while read NT MK do echo "route add -net $NT netmask $MK gw $ip " >>route.rule done < a.txt #删除临时文件 rm -rf a.txt

     

    service_net是k8s service的网段,即coredns的service ip所在的网段,service_mask是k8s service的子网掩码,这个在使用kubeadm初始化的时候就指定了,我们使用的是:

    https://www.cnblogs.com/cuishuai/p/9897006.html

     podSubnet: 192.244.0.0/16
    
     serviceSubnet: 192.96.0.0/16

    将service_net、service_mask换成自己的。

    然后将生成的文件copy到物理机上,然后执行:

    sh  route.rule

     

    在物理机上面在/etc/resolv.conf里面添加coredns的service的ip,service名称是kube-dns,在任意master节点上查看:

    kubectl get svc -n kube-system | grep kube-dns
    kube-dns         ClusterIP   192.96.0.10      <none>        53/UDP,53/TCP   7d8h

     

    将找到的ip地址添加到/etc/resolv.conf:

    nameserver 192.96.0.10

     

    在物理机上面测试连通性:

     

  • 相关阅读:
    嵌入式C语言编程小技巧
    冒号:在linux bash中的各种用法
    巧用ls命令
    嵌入式C精华提炼1
    不知道这些,别说你是嵌入式工程师!
    这些ARM基础知识你还不知道吗
    代码示例_C_冒泡
    代码示例_文件IO_lseek
    代码示例_文件IO_read / write
    代码示例_标准IO_fseek
  • 原文地址:https://www.cnblogs.com/cuishuai/p/10310698.html
Copyright © 2020-2023  润新知