让外部的开发机直接访问Kubernetes群集内的服务!

1.场景

容器化+K8s编排已经是现在进行时
把网站的多个项目设计为云原生(Cloud Native)或老项改造为云原生可以获得诸多能力
例如无云绑定、弹性、部署环境一致性、微服务、DevOps、持续交付
同时下一代微服务框架 服务网格(ServiceMesh) 也能无痛接入

博主现有项目后端开发语言为 PHP、Golang
Golang做一些基础公共服务(短信、消息、搜索等)
这些公共服务化的项目已经容器化
PHP的项目做应用逻辑层,会调用Golang写的一些公共基础服务
PHP项目中直接通过服务名调用服务

需求: PHP项目A 依赖 短信、消息、搜索这3个服务,开发人员无需在本机启动依赖的服务,通过服务直接名透明的调用开发环境dev下的服务,开发人员只需要关注PHP项目A的开发。

☆本文的方案完成了开发人员开发机透明的直接访问K8s服务,从而满足了本需求☆

需要开发机透明访的直接问Kubernetes群集内的服务本文讲的方案都适用

开发机直接访问Kubernetes群集内的服务 示意图

2.基本信息和完成的目标

2.1基本信息

开发办公内网 192.168.1.0/24
开发机2 192.168.1.2

运行K8s群集的Node网络 10.2.0.0/16
Node1 10.2.1.4
Node2 10.2.1.8
K8s 群集网络 10.3.0.0/16

部署deployment whoami服务用于测试
命名空间 default (这里可以用命名空间来区分环境例如dev为开发环境)
镜像 wwek/whoami
服务名 whoami

Pod ip
10.3.0.8在node1 10.2.1.4
10.3.0.70在node2 10.2.1.8

2.3完成的目标

开发机2 192.168.1.2 可以直接访问 whoami服务
也就是可以直接 curl http://whomai 就可以访问服务
本目标即完成需求

3.网络互通1 开发办公内网 <==> 公有云VPC(私有云内网)基础互通

开发办公内网 和 公有云VPC、私有云内网 网络互通

和公有云互通的方案
公有云VPN
专线(SDWAN)

私有云互通就不多讲了,很多公司内网的K8s开发测试群集和开发网络本身就是互通的

各家网络情况各有各的不同,相同的是这些有用的Tips
无论是在公有云VPC、私有云、K8s群集非常关键的一点,子网网段不要冲突不要冲突、子网网段不要冲突、子网网段不要冲突
做基础互通的时候善用公有云的VPC和路由配置功能
甚至你可以不用买公有云自带的VPN网关服务,直接配合VPC路由表用一台VM充当路由器网关、VPN网关
开发测试环境下用zerotier来打通各个内网性价比极高

最终要完成是 开发办公内网 和 公有云VPC(私有云内网) 基础互通

4.网络互通2 开发办公内网 <==> K8s群集内部Pod和Service网络

☆☆☆ K8s Node本身是直接可以访问K8s群集内部Pod网络的!☆☆☆
在Node1上用ping/curl测试 whoami服务 分布在2个Node的2个Pod

可以看到,whoami的2个pod ip都能ping通,用curl测试也能访问到

通过Edge Node互通K8s群集和开发办公之间的网络
那么用Node1作为 开发办公内网 和 K8s群集内部网络的“连接”点我们把这个Node1节点叫做 边缘节点(Edge Node)
边缘节点(Edge Node)可以在运行K8s群集中Node中随便选一个
这里选择Node1,他的网卡信息如下
eth0 vm网卡 ip 10.2.1.4
cbr0 K8s群集创建的网卡 ip 10.3.0.1

可以有2种方式
方式1 在 Edge Node eth0 上启用NAT 这样其他的子网的访问在K8s群集中看到的IP是 10.2.1.4
方式2 K8s群集子网和开发办公内网完全对等互通(公有云VPC路由表、开发办公网络路由表配合做)

完成后
开发办公网络中 在开发机2 192.168.1.2 ping/curl K8s群集中的pod ip

可ping/curl 属于whoami的2个Pod ip

㊗️网络搞通了,那么再解决DNS解析的问题就可以了

5.打通K8s群集中的DNS (开发办公内网的DNS,设置K8s中KubeDns为上游DNS)

在Edge Node1上可以直接访问到KubeDns

kubectl get svc -n kube-system
#kube-dns ip 10.3.254.107

那么在Edge Node1上面装一个DNS Server做个中间转发(使用CoreDNS)
开发网络中的电脑无法直接使用kube-dns,非Edge Node解析结果为空
所以需要在Edge Node1上转一个 DNS Server 做一个Proxy
CoreDNS的安装使用参考我的另外一篇文章
使用CoreDNS作为你的内网DNS服务器
可用CoreDNS配置文件参考
/etc/coredns/Corefile

# kubernetes设置
cluster.local:53 {
  # kube-dns
  forward . 10.3.254.107:53
  log
  errors
  #debug
}

# 默认设置
.:53 {
  # 先走本机的hosts
  # https://coredns.io/plugins/hosts/
  hosts {
    # 自定义sms.service search.service 的解析
    # 因为解析的域名少我们这里直接用hosts插件即可完成需求
    # 如果有大量自定义域名解析那么建议用file插件使用 符合RFC 1035规范的DNS解析配置文件
    #10.6.6.2 servicename
    # ttl
    ttl 60
    # 重载hosts配置
    reload 1m
    # 继续执行
    fallthrough
  }

  # file enables serving zone data from an RFC 1035-style master file.
  # https://coredns.io/plugins/file/
  # file service.signed service
  # 最后所有的都转发到系统配置的上游dns服务器去解析
  forward . /etc/resolv.conf

  # 缓存时间ttl  s
  #cache 6
  # 自动重新加载配置文件的间隔时间
  reload 6s
  # 输出日志
  log
  # 输出错误
  errors
  #debug
}

启动CoreDNS

dig @10.2.1.4 whoami.default.svc.cluster.local
# 测试下确保可以解析

在 开发机2
配置DNS为 Edge Node1 IP 10.2.1.4
配置搜索域为 default.svc.cluster.local

这个2个配置可以在开发办公网络中的DHCP服务器上统一配置

-w564

来测试下DNS解析 curl访问

6.关键实现总结

  • 网络互通1 开发办公内网 <==> 公有云VPC(私有云内网)基础互通
  • 网络互通2 开发办公内网 <==> K8s群集内部Pod和Service网络(通过Edge Node)
  • 打通K8s群集中的DNS (开发办公内网的DNS,设置K8s中KubeDns为上游DNS)
  • 开发机DNS配置 Edge Node DNS 和 搜索域设置default.svc.cluster.local

7.QA

问1:这也太复杂了吧,有没有简单点的?
答:
解决的目标不同

如果只是单纯的能访问k8s中的服务有以下的方式
访问K8s中的服务还有这些方式
telepresence (快速,本地开发面向k8s的微服务)
K8s中装个openvpn 拨入群集内网络
K8s自带的服务暴露方式 NodePort Ingress

这些方法在一个应用有多个服务依赖的时候无法做到让所有开发人员透明的直接通过服务名调用

为了做到对多个开发人员透明,所有人都不需要安装项目依赖的服务,只需要运行项目本身,本项目透明的调用依赖的服务。
所以才有了本文的“复杂”方案

问2:这样直通了暴露K8s群集后岂不是不安全?
答:
是的,但是可以解决,我是这么解决的
K8s群集分为线上和线下实现了隔离
线上为准生产、生产,线下为开发、测试
k8s中可以用命名空间(namespace)来做环境的区分
dev、testing、staging、prod

问题3:开发机中DNS用K8s的DNS作为上游后网站的CDN乱解析了!
答:
开发办公网络和公有云的网络运营商和地理位置都不同,
也就是如果网络出口不一样这会导致CDN解析的IP是错的

需要在开发办公网络也部署一个DNS Server成为二级DNS
开发办公网络 开发机设置DNS为这个二级DNS
cluster.local转发到 Edge Node DNS上
其他的走本地默认的DNS
同样采用CoreDNS,配置文件参考

cluster.local:53 {
  # Edge Node DNS
  forward . 10.2.1.4:53
  log
  errors
  #debug
}
.:53 {
   ....
}

私有云或者自己在开发办公网络部署的K8s群集,因为是同一个网络出口那么网站的DNS解析应该不会有问题

发表回复