想象一下,如果您日常使用的研发测试Kubernetes集群,能够有以下效果:

  • 在办公网络下直接访问Pod IP
  • 在办公网络下直接访问Service Cluster IP
  • 在办公网络下直接访问集群内部域名,类似 service.namespace.svc.cluster.local

会不会很方便,很优雅?

笔者近期就给内部的一个新集群做过类似的调整,特此分享一些心得。

PS: 这里的 直接访问/直连 指的是不借助Ingress/hostnetwork:true/NodePort等常规方式,直接访问k8s内部IP or DNS,起到 网络拉平 的效果。

先决条件 - 三层路由方案

办公网段跟Kubernetes集群大概率是不同的网段,所以要想打通最自然的想法是依赖路由。相应的,Kubernetes 跨主机网络方案,我们最好也选择三层路由方案或者Host-GW,而非Overlay,不然数据包在封包解包过程中可能会失去路由方向。

我们的集群选用的是Calico,且关闭了 IPIP 模式。具体的IPPool配置如下:

  1. -> calicoctl get IPPool -o yaml
  2. apiVersion: projectcalico.org/v3
  3. items:
  4. - apiVersion: projectcalico.org/v3
  5. kind: IPPool
  6. metadata:
  7. name: default-pool
  8. spec:
  9. blockSize: 24
  10. cidr: 10.233.64.0/18
  11. # 关闭IPIP模式
  12. ipipMode: Never
  13. natOutgoing: true
  14. nodeSelector: all()
  15. vxlanMode: Never
  16. kind: IPPoolList

Calico RR(Route Reflectors)or Full-Mesh 模式?

网上的很多类似教程,上来都会引导大家先把集群改为RR模式,其实这不是必须的。大家可以思考下,RR模式解决的问题是什么?是为了防止所有节点间都做BGP连接交换,浪费资源。但如果你的集群很小, 且已经是按Full Mesh模式部署了,到也没必要非得改为RR模式。Full Mesh下所有的节点都是类似RR节点的效果,所以如果我们想选择作为 BGPPeer交换的节点,选择任意节点就行。 比如,笔者的集群就选择了Ingress所在的节点,作为BGPPeer。

  1. ~ calicoctl get BGPPeer -o yaml
  2. apiVersion: projectcalico.org/v3
  3. items:
  4. - apiVersion: projectcalico.org/v3
  5. kind: BGPPeer
  6. metadata:
  7. name: peer-switch
  8. spec:
  9. # 交换机配置
  10. asNumber: 65200
  11. peerIP: 10.200.20.254
  12. # 这个label是Ingress节点特有的
  13. nodeSelector: node-role.kubernetes.io/ingress == 'ingress'
  14. kind: BGPPeerList

从集群外部访问Pod IP vs 从集群内部访问?

这个问题很关键,如果我们想从外部直接访问到集群内部的Pod IP,那么首先需要搞清楚集群内的节点是如何畅通访问的。

以下面的节点为例,我们来看它的路由信息:

  1. ~ ip r
  2. # 默认路由
  3. default via 10.200.20.21 dev bond0 onlink
  4. # 宿主机数据包路由
  5. 10.200.20.0/24 dev bond0 proto kernel scope link src 10.200.20.105
  6. # 黑洞,防止成环
  7. blackhole 10.233.98.0/24 proto bird
  8. # 目的地址是10.233.98.3的数据包,走cali9832424c93e网卡
  9. 10.233.98.3 dev cali9832424c93e scope link
  10. # 目的地址是10.233.98.4的数据包,走cali4f5c6d27f17网卡
  11. 10.233.98.4 dev cali4f5c6d27f17 scope link
  12. # 目的地址是10.233.98.8的数据包,走cali8f10abc672f网卡
  13. 10.233.98.8 dev cali8f10abc672f scope link
  14. # 目的地址是10.233.110.0/24网段的数据包,从bond0网卡出到下一跳10.200.20.107上
  15. 10.233.110.0/24 via 10.200.20.107 dev bond0 proto bird
  16. # 目的地址是10.233.112.0/24网段的数据包,从bond0网卡出到下一跳10.200.20.106上
  17. 10.233.112.0/24 via 10.200.20.106 dev bond0 proto bird
  18. # 目的地址是10.233.115.0/24网段的数据包,从bond0网卡出到下一跳10.200.20.108上
  19. 10.233.115.0/24 via 10.200.20.108 dev bond0 proto bird

相信看了笔者的注释,大家应该很容易了解到以下信息:

  • 这台宿主机IP是10.200.20.105,集群内其他的宿主机还有10.200.20.106, 10.200.20.107, 10.200.20.108等
  • 主机10.200.20.105上的Pod IP段是10.233.98.0/24, 10.200.20.106上是10.233.112.0/24,10.200.20.107上是10.233.110.0/24
  • 目的地址是10.233.98.3的数据包走cali9832424c93e网卡,目的地址10.233.98.4的数据包走cali4f5c6d27f17网卡等

而这些信息实际解答了,容器数据包的 出和入 这个关键问题:

  • 比如想访问Pod IP为10.233.110.7的容器,宿主机自然知道下一跳是10.200.20.107上
  • 比如接收到了目的地址是10.233.98.8的数据包,宿主机自然也知道要把这个包交给cali8f10abc672f网卡。而这个网卡是veth pair设备的一端,另一端必然在目标Pod里

那这些路由信息是哪里来的呢?自然是Calico借助BGP的能力实现的。我们进一步想,如果外部节点也有这些信息,是不是也就自然知道了Pod IP在哪里了? 答案确实如此,其实总结基于Calico的网络打平方案,核心原理就是 通过BGP能力,将集群路由信息广播给外部。

而在具体的配置上,就比较简单了,只需要在两端配置好BGP Peer即可。

  • 先是集群这一侧,前面笔者已给出:

    1. ~ calicoctl get BGPPeer -o yaml
    2. apiVersion: projectcalico.org/v3
    3. items:
    4. - apiVersion: projectcalico.org/v3
    5. kind: BGPPeer
    6. metadata:
    7. name: peer-switch
    8. spec:
    9. # 交换机配置
    10. asNumber: 65200
    11. peerIP: 10.200.20.254
    12. # 这个label就是Ingress节点特有的
    13. nodeSelector: node-role.kubernetes.io/ingress == 'ingress'
    14. kind: BGPPeerList
  • 再就是外部,一般是交换机,使用类似下面的命令:

    1. [SwitchC] bgp 64513 # 这是k8s集群的ASN
    2. [SwitchC-bgp] peer 10.200.20.107 as-number 64513
    3. [SwitchC-bgp] peer 10.200.20.108 as-number 64513

    PS: 具体的交换机操作方式可以参考各品牌交换机官方文档

到这里,基本上我们已经打通了外部直接访问Pod IP的能力。当然,如果您的办公网络到交换机这一侧还有多个网关,您还需要在这些网关上设置合适的路由才行。

为什么 Service Cluster IP 还不能访问?

也许这时候您会发现,可以直连Pod IP,但 Cluster IP不可以,这是为什么呢?原来,默认情况Calico并没有广播Service IP,您可以在交换机这一侧通过查看交换过来的IP段来确认这一点。

PS: 您是否注意到,k8s主机节点上也没有service的ip路由,但为啥在集群内部访问service没有问题呢?

解决方案也简单,只要打开相关的设置即可, 类似如下:


  1. ~ calicoctl get bgpconfig default -o yaml
  2. apiVersion: projectcalico.org/v3
  3. kind: BGPConfiguration
  4. metadata:
  5. name: default
  6. spec:
  7. asNumber: 64513
  8. listenPort: 179
  9. logSeverityScreen: Info
  10. nodeToNodeMeshEnabled: true
  11. # 这就是需要广播的service cluster IP 段
  12. serviceClusterIPs:
  13. - cidr: 10.233.0.0/18

打通内网DNS,直接访问Service域名

直连IP虽然方便,但有时若想记住某服务的具体IP却不是那么容易。所以,我们将K8s内部的DNS域名也暴漏出来了,类似下面:

  1. <service>.<namespaces>.svc.cluster.local

而这块的设置也相对简单,一般企业都有内网DNS,只需要添加相应解析到K8s内部DNS Server即可。

总结

其实若想打造一个好用的研发测试集群,有很多的细节需要处理,笔者后续也会继续分享类似的经验,希望对大家有用。

参考链接

聊聊如何让办公网络直连Kubernetes集群PodIP/ClusterIP/Service DNS等的更多相关文章

  1. 在Kubernetes集群中使用calico做网络驱动的配置方法

    参考calico官网:http://docs.projectcalico.org/v2.0/getting-started/kubernetes/installation/hosted/kubeadm ...

  2. Kubernetes集群中Service的滚动更新

    Kubernetes集群中Service的滚动更新 二月 9, 2017 0 条评论 在移动互联网时代,消费者的消费行为已经“全天候化”,为此,商家的业务系统也要保持7×24小时不间断地提供服务以满足 ...

  3. Kubernetes(K8s) 安装(使用kubeadm安装Kubernetes集群)

    背景: 由于工作发生了一些变动,很长时间没有写博客了. 概述: 这篇文章是为了介绍使用kubeadm安装Kubernetes集群(可以用于生产级别).使用了Centos 7系统. 一.Centos7 ...

  4. vivo 公司 Kubernetes 集群 Ingress 网关实践

    文章转载自:https://mp.weixin.qq.com/s/qPqrJ3un1peeWgG9xO2m-Q 背景 vivo 人工智能计算平台小组从 2018 年底开始建设 AI 计算平台至今,已经 ...

  5. 三十二、kubernetes集群的网络实现

    Kubernetes集群的网络实现 CNI介绍及集群网络选型 容器网络接口(Container Network Interface),实现kubernetes集群的Pod网络通信及管理.包括: CNI ...

  6. 高可用Kubernetes集群-5. 部署flannel网络

    七.部署flannel网络 kubernetes支持基于vxlan方式的flannel与weave网络,基于BGP路由的Calico网络,本节采用flannel网络. Flannel网络采用etcd等 ...

  7. k8s教程:Kubernetes集群使用网络存储NFS

    NFS存储 NFS即网络文件系统Network File System,它是一种分布式文件系统协议,最初是由Sun MicroSystems公司开发的类Unix操作系统之上的一款经典网络存储方案,其功 ...

  8. Kubernetes集群的部署方式及详细步骤

    一.部署环境架构以及方式 第一种部署方式 1.针对于master节点 将API Server.etcd.controller-manager.scheduler各组件进行yum install.编译安 ...

  9. 使用 Kubeadm+Containerd 部署一个 Kubernetes 集群

    本文独立博客阅读地址:https://ryan4yin.space/posts/kubernetes-deployemnt-using-kubeadm/ 本文由个人笔记 ryan4yin/knowle ...

  10. Docker 与 K8S学习笔记(二十三)—— Kubernetes集群搭建

    小伙伴们,好久不见,这几个月实在太忙,所以一直没有更新,今天刚好有空,咱们继续k8s的学习,由于我们后面需要深入学习Pod的调度,所以我们原先使用MiniKube搭建的实验环境就不能满足我们的需求了, ...

随机推荐

  1. K8S_删除Pod总结

    K8S 不能直接删除Pod,直接删除Pod,会被Deployment重启 删除前,必须先删除对应的Deployment 例子: // 查出Pod [root@k8s-master ~]# kubect ...

  2. 《网页设计基础——HTML常用标签》

    网页设计基础--HTML常用标签       一.网页框架: 格式: <html> <head> <title>网页标题</title> <sty ...

  3. Django 运行报异常:AttributeError: 'str' object has no attribute 'get'

    Technorati Tags: Python,Django,Web 在使用django.contrib.auth用户机制进行用户的验证.登录.注销操作时,遇到这个异常. 首先是写了一个登录的视图,要 ...

  4. Kubernetes实践技巧:Windows 系统最佳实践

    有部分同学是使用的 Windows 系统,我们的直播课程也是在 Windows 系统下面进行的,然后通过 SSH 方式连接到 服务器上面操作 Kubernetes,由于对 vim 不是很熟悉,所以又通 ...

  5. kubepi访问

    ko最新版本会默认安装kubepi,端口没有对外暴露,点击dashboard打开的就是默认安装的kubepi 如果安装了最新版本的ko,之前单独运行的kubepi就可以stop了

  6. es证书生成方式

    ./bin/elasticsearch-certutil ca --pem # 生成一个名字叫做elastic-stack-ca.zip的文件 unzip elastic-stack-ca.zip A ...

  7. 2022IDEA破解

    注意 本教程适用于 IntelliJ IDEA 2022.1.2 以下所有版本,请放心食用~ 本教程适用于 JetBrains 全系列产品,包括 IDEA.Pycharm.WebStorm.Phpst ...

  8. 【机器学习】利用 Python 进行数据分析的环境配置 Windows(Jupyter,Matplotlib,Pandas)

    环境配置 安装 python 博主使用的版本是 3.10.6 在 Windows 系统上使用 Virtualenv 搭建虚拟环境 安装 Virtualenv 打开 cmd 输入并执行 pip inst ...

  9. 【算法训练营day4】LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表II

    [算法训练营day4]LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表 ...

  10. 设计一个网上书店,该系统中所有的计算机类图书(ComputerBook)每本都有10%的折扣,所有的语言类图书(LanguageBook)每本都有2元的折扣,小说类图书(NovelBook)每100元

    现使用策略模式来设计该系统,绘制类图并编程实现 UML类图 书籍 package com.zheng; public class Book { private double price;// 价格 p ...