Kubernetes | Nginx Ingress Controller as TCP Proxy

2021 01 12, Tue

昨天搞了http的部分,用ingress资源就可以很方便的配置http代理。但是有个问题是我要部署git托管,就需要ssh代理。ingress并不能定义tcp流量,怎么办呢?

流量是怎么流动的

回顾一下Nginx Ingress Controller都有什么,或者说,流量都经过了谁:

  1. 一个连通公网的LoadBalancer或者NodePort类型的Service
  2. Service把流量给Controller
  3. Controller把流量给后端的Service
  4. Service把流量给具体的服务

对于我们来说,我们就需要让Controller可以接受从公网来、发给NodePort或者LB的22端口的流量,传给后端的服务。

需要做的事情

梳理清楚要做什么,剩下的问题就剩下怎么做和实施了。

公网监听22端口

既然都是通过Service监听一个IP,Service通过NodePort提供服务,那你还需要暴露22端口。LoadBalancer和NodePort的区别无非是vendor提供的LoadBalancer自动配置22端口,还是在节点上监听22端口。

这样22端口就可以提供公共服务了,顺便配置了Service。

配置Nginx Ingress Controller

既然Ingress不支持Tcp代理,那我用最土的配置文件配置流量就行了啊。Nginx Ingress Controller启动提供了两个参数,用来指定配置tcp或者udp代理配置所在的ConfigMap。

阿里的ingress controller创建的时候已经生成这样的一个ConfigMap了。我们只要填内容进去就行。

apiVersion: v1
data:
  "22": gitea/gitea-ssh:22
kind: ConfigMap
metadata:
  name: tcp-services
  namespace: kube-system

验证

用nc就可以知道有没有问题了

nc -z <public address> 22 && echo ok || echo err

从nginx ingress controller也可以看到配置文件变动、并且reload成功。

思考一下

config map和文本配置其实大同小异。有的时候我们会写错东西什么的。有没有什么更好的办法定义tcp入流量?