内容简介:由于开发有部份服务使用 GRPC 进行通讯,同时采用 Consul 进行服务发现;在微服务架构下可能会导致一些访问问题,目前解决方案就是打通开发环境网络与测试环境 Kubernetes 内部 Pod 网络;翻了好多资料发现都是 2.x 的,而目前测试集群 Calico 版本为 3.6.3,很多文档都不适用只能自己折腾,目前折腾完了这里记录一下在微服务架构下,由于服务组件很多,开发在本地机器想测试应用需要启动整套服务,这对开发机器的性能确实是个考验;但如果直接连接测试环境的服务,由于服务发现问题最终得到的具体
由于开发有部份服务使用 GRPC 进行通讯,同时采用 Consul 进行服务发现;在微服务架构下可能会导致一些访问问题,目前解决方案就是打通开发环境网络与测试环境 Kubernetes 内部 Pod 网络;翻了好多资料发现都是 2.x 的,而目前测试集群 Calico 版本为 3.6.3,很多文档都不适用只能自己折腾,目前折腾完了这里记录一下
本文默认为读者已经存在一个运行正常的 Kubernetes 集群,并且采用 Calico 作为 CNI 组件,且 Calico 工作正常;同时应当在某个节点完成了 calicoctl 命令行 工具 的配置
一、问题描述
在微服务架构下,由于服务组件很多,开发在本地机器想测试应用需要启动整套服务,这对开发机器的性能确实是个考验;但如果直接连接测试环境的服务,由于服务发现问题最终得到的具体服务 IP 是 Kubernetes Pod IP,此 IP 由集群内部 Calico 维护与分配,外部不可访问;最终目标为打通开发环境与集群内部网络,实现开发网络下直连 Pod IP,这或许在以后对生产服务暴露负载均衡有一定帮助意义;目前网络环境如下:
开发网段: 10.10.0.0/24
测试网段: 172.16.0.0/24
Kubernetes Pod 网段: 10.20.0.0/16
二、打通网络
首先面临的第一个问题是 Calico 处理,因为 如果想要让数据包能从开发网络到达 Pod 网络,那么必然需要测试环境宿主机上的 Calico Node 帮忙转发 ;因为 Pod 网络由 Calico 维护,只要 Calico Node 帮忙转发那么数据一定可以到达 Pod IP 上;
一开始我很天真的认为这就是个 ip route add 10.20.0.0/16 via 172.16.0.13
的问题… 后来发现
经过翻文档、issue、blog 等最终发现需要进行以下步骤
2.1、关闭全互联模式
注意: 关闭全互联时可能导致网络暂时中断,请在夜深人静时操作
首先执行以下命令查看是否存在默认的 BGP 配置
calicoctl get bgpconfig default
如果存在则将其保存为配置文件
calicoctl get bgpconfig default -o yaml > bgp.yaml
修改其中的 spec.nodeToNodeMeshEnabled
为 false
,然后进行替换
calicoctl apply -f bgp.yaml
如果不存在则手动创建一个配置,然后应用
cat << EOF | calicoctl create -f - apiVersion: projectcalico.org/v3 kind: BGPConfiguration metadata: name: default spec: logSeverityScreen: Info nodeToNodeMeshEnabled: false asNumber: 63400 EOF
本部分参考:
2.2、开启集群内 RR 模式
在 Calico 3.3 后支持了集群内节点的 RR 模式,即将某个集群内的 Calico Node 转变为 RR 节点;将某个节点设置为 RR 节点只需要增加 routeReflectorClusterID
既可,为了后面方便配置同时增加了一个 lable 字段 route-reflector: "true"
calicoctl get node CALICO_NODE_NAME -o yaml > node.yaml
然后增加 routeReflectorClusterID
字段,样例如下
apiVersion: projectcalico.org/v3 kind: Node metadata: annotations: projectcalico.org/kube-labels: '{"beta.kubernetes.io/arch":"amd64","beta.kubernetes.io/os":"linux","kubernetes.io/hostname":"d13.node","node-role.kubernetes.io/k8s-master":"true"}' creationTimestamp: 2019-06-17T13:55:44Z labels: beta.kubernetes.io/arch: amd64 beta.kubernetes.io/os: linux kubernetes.io/hostname: d13.node node-role.kubernetes.io/k8s-master: "true" route-reflector: "true" # 增加 lable name: d13.node resourceVersion: "61822269" uid: 9a1897e0-9107-11e9-bc1c-90b11c53d1e3 spec: bgp: ipv4Address: 172.16.0.13/19 ipv4IPIPTunnelAddr: 10.20.73.82 routeReflectorClusterID: 172.16.20.1 # 添加集群 ID orchRefs: - nodeName: d13.node orchestrator: k8s
事实上我们应当导出多个 Calico Node 的配置,并将其配置为 RR 节点以进行冗余;对于 routeReflectorClusterID
目前测试只是作为一个 ID(至少在本文是这样的),所以理论上可以是任何 IP,个人猜测最好在同一集群网络下采用相同的 IP,由于这是真正的测试环境我没有对 ID 做过多的测试(怕玩挂)
修改完成后只需要应用一下就行
calicoctl apply -f node.yaml
接下来需要创建对等规则,规则文件如下
kind: BGPPeer apiVersion: projectcalico.org/v3 metadata: name: peer-to-rrs spec: nodeSelector: "!has(route-reflector)" peerSelector: has(route-reflector) --- kind: BGPPeer apiVersion: projectcalico.org/v3 metadata: name: rr-mesh spec: nodeSelector: has(route-reflector) peerSelector: has(route-reflector)
假定规则文件名称为 rr.yaml
,则创建命令为 calicoctl create -f rr.yaml
;此时在 RR 节点上使用 calicoctl node status
应该能看到类似如下输出
Calico process is running. IPv4 BGP status +--------------+---------------+-------+----------+-------------+ | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO | +--------------+---------------+-------+----------+-------------+ | 172.16.0.19 | node specific | up | 05:43:51 | Established | | 172.16.0.16 | node specific | up | 05:43:51 | Established | | 172.16.0.17 | node specific | up | 05:43:51 | Established | | 172.16.0.13 | node specific | up | 13:01:17 | Established | +--------------+---------------+-------+----------+-------------+ IPv6 BGP status No IPv6 peers found.
PEER ADDRESS
应当包含所有非 RR 节点 IP(由于真实测试环境,以上输出已人为修改)
同时在非 RR 节点上使用 calicoctl node status
应该能看到以下输出
Calico process is running. IPv4 BGP status +--------------+---------------+-------+----------+-------------+ | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO | +--------------+---------------+-------+----------+-------------+ | 172.16.0.10 | node specific | up | 05:43:51 | Established | | 172.16.0.13 | node specific | up | 13:01:20 | Established | +--------------+---------------+-------+----------+-------------+ IPv6 BGP status No IPv6 peers found.
PEER ADDRESS
应当包含所有 RR 节点 IP,此时原本的 Pod 网络连接应当已经恢复
本部分参考:
2.3、调整 IPIP 规则
先说一下 Calico IPIP 模式的三个可选项:
Always CrossSubnet Never
在默认情况下,默认的 ipPool 启用了 IPIP 封装(至少通过官方安装文档安装的 Calico 是这样),并且封装模式为 Always
;这也就意味着任何时候都会在原报文上封装新 IP 地址, 在这种情况下将外部流量路由到 RR 节点,RR 节点再转发进行 IPIP 封装时,可能出现网络无法联通的情况(没仔细追查,网络渣,猜测是 Pod 那边得到的源 IP 不对导致的); 此时我们应当调整 IPIP 封装策略为 CrossSubnet
导出 ipPool 配置
calicoctl get ippool default-ipv4-ippool -o yaml > ippool.yaml
修改 ipipMode
值为 CrossSubnet
apiVersion: projectcalico.org/v3 kind: IPPool metadata: creationTimestamp: 2019-06-17T13:55:44Z name: default-ipv4-ippool resourceVersion: "61858741" uid: 99a82055-9107-11e9-815b-b82a72dffa9f spec: blockSize: 26 cidr: 10.20.0.0/16 ipipMode: CrossSubnet natOutgoing: true nodeSelector: all()
重新使用 calicoctl apply -f ippool.yaml
应用既可
本部分参考:
2.4、增加路由联通网络
万事俱备只欠东风,最后只需要在开发机器添加路由既可
将 Pod IP 10.20.0.0/16
和 Service IP 10.254.0.0/16
路由到 RR 节点 172.16.0.13
# Pod IP ip route add 10.20.0.0/16 via 172.16.0.13 # Service IP ip route add 10.254.0.0/16 via 172.16.0.13
当然最方便的肯定是将这一步在开发网络的路由上做,设置完成后开发网络就可以直连集群内的 Pod IP 和 Service IP 了;至于想直接访问 Service Name 只需要调整上游 DNS 解析既可
转载请注明出处,本文采用 CC4.0 协议授权
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。