Ingress nginx 公开TCP服务

背景

公司业务繁多, HTTP、GRPC、TCP多种协议服务并存,Kubernetes流量入口复杂,所以萌生了通过LoadBalancer + Ingress-nginx 的方式完全的结果入口流量,当然在高并发的场景下可以对LoadBalancer 和Ingress-nginx 进行拆分管理。

HTTP以及GRPC在Ingress上的使用就不过多说明了。 主要验证下ingres-nginx对TCP流量的转发,以及简单窥探下实现逻辑。

搞起

首先先准备好内部TCP环境, 这里使用mysql作为测试服务,使用如下命令对服务进行部署。

cat > mysql.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-master
  labels:
    name: mysql-master
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql-master
      name: mysql-master
  template:
    metadata:
      labels:
        app: mysql-master
        name: mysql-master
    spec:
      containers:
      - name: mysql-master
        image: mysql:9
        imagePullPolicy: Always
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "123456"
---
kind: Service
apiVersion: v1
metadata:
  name: mysql
  namespace: default
spec:
  type: ClusterIP
  clusterIP: None
  ports:
   - name: mysql
     port: 3306
  selector:
    name: mysql-master
---
# 创建ingress tcp转发用到的configmap
apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services
  namespace: ingress-nginx
data:
  9000: "default/mysql:3306"
EOF
kubectl apply -f mysql.yaml

ingress对于TCP与UDP的转发通过增加--tcp-services-configmap--udp-services-configmap参数配置,用于指定配置保存的configmap。
configmap 格式如下:
<external port>:<namespace/service name>:<service port/name>:[PROXY]:[PROXY]

  • external port:表示ingress对外暴露的端口,需要在ingress service进行添加。 下一步添加。
  • <namespace/service name>:service 所在的namespace及名称。
  • <service port/name>:service的名称或端口。
  • [PROXY]:[PROXY]:TCP 服务中使用代理协议解码 (listen) 和/或编码 (proxy_pass)。第一个PROXY控制代理协议的解码,第二个PROXY控制使用代理协议的编码。(可选)

拓展( PROXY Protocol )

什么是 PROXY Protocol ? 其实很简单,就是为了解决多层NET或TCP转发时 无法获取客户端真实IP的问题,在 TCP 第一行加入了一些信息标识协议、客户端地址、转发地址以及端口等。目前有 v1 和 v2 两个版本。

开源版本支持:

  • HTTP 的 PROXY 协议:NGINX Open Source 1.5.12及更高版本
  • TCP 客户端 PROXY 协议:NGINX Open Source 1.9.3及更高版本
  • 接受 TCP 的 PROXY 协议:NGINX Open Source 1.11.4及更高版本
  • PROXY 协议 v2:NGINX Open Source 1.13.11及更高版本
    NGINX Open Source 默认不包含HTTP和Stream TCP的 Real-IP 模块;

一般获取客户端真实IP有以下2种方案:

HTTP:

  • 使用 X-Forwarded-For(XFF)头
  • Proxy Protocol + X-Forwarded-For

TCP:

  • Proxy Protocol + nginx日志分析
  • 基于网络层信息获取(toa)

然后接着说, 需要对ingress-nginx service 开启相应的端口转发,增加如下配置。

    - name: proxied-tcp-9000
      port: 9000
      targetPort: 9000
      protocol: TCP

最后,修改ingress-nginx deployment , 在启动参数中加入如下配置,用来更新nginx 关于TCP/UDP的转发配置。

args:
    - /nginx-ingress-controller
    - --tcp-services-configmap=ingress-nginx/tcp-services

完结~撒花🎉~~

参考

nginx-ingress 服务架构图
在这里插入图片描述
根据配置的信息自动加载后端IP、Port (https://github.com/kubernetes/ingress-nginx/blob/main/rootfs/etc/nginx/lua/tcp_udp_balancer.lua)
在这里插入图片描述

### Nginx Ingress Controller概述 Nginx Ingress Controller是一种用于Kubernetes集群中的入口控制器,其主要功能是在集群外部流量进入集群内部时提供路由管理。通过定义Ingress资源对象来描述HTTP(S)负载均衡器的行为模式以及如何将请求转发给后端服务[^1]。 ### 部署Nginx Ingress Controller #### 下载YAML文件 为了安装Nginx Ingress Controller,在官方文档或其他可靠源处获取最新的部署清单(manifests)。通常这些文件会打包成`.yaml`格式并命名为类似`nginx-ingress-controller.yaml`或`mandatory.yaml`的形式。 #### 修改Mandatory.Yaml文件 下载完成后可能需要根据实际环境调整部分参数设置,比如更改默认的Service Type为NodePort或者LoadBalancer;指定特定版本镜像等操作均在此阶段完成。 #### 给节点打标签 如果希望某些Pod仅调度到具有特殊硬件特性的机器上,则可以通过kubectl命令为那些目标主机添加相应的key-value对形式的label标记。 ```bash kubectl label nodes <node-name> ingress=true ``` #### 执行部署过程 当一切准备就绪之后就可以利用kubectl apply指令提交修改后的配置文件至API Server从而触发整个应用层面上的变化生效流程了: ```bash kubectl apply -f mandatory.yaml ``` ### 示例验证 #### 使用以下YAML文件部署Tomcat 创建一个新的命名空间以便更好地隔离测试项目,并引入一个简单的Web应用程序作为演示用途——这里选用Apache Tomcat为例说明具体步骤如下所示: ```yaml apiVersion: v1 kind: Namespace metadata: name: demo-space --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: tomcat-sample-app name: tomcat-deployment namespace: demo-space spec: replicas: 2 selector: matchLabels: app: tomcat-sample-app template: metadata: labels: app: tomcat-sample-app spec: containers: - image: harbor.com/library/tomcat:latest name: tomcat-container ports: - containerPort: 8080 protocol: TCP --- apiVersion: v1 kind: Service metadata: labels: app: tomcat-sample-service name: tomcat-cluster-ip-svc namespace: demo-space spec: type: ClusterIP selector: app: tomcat-sample-app ports: - port: 8080 targetPort: 8080 protocol: TCP ``` #### 创建访问Tomcat服务Ingress 接下来编写一段新的资源配置用来声明对外暴露路径规则及关联的服务名称/端口号信息等内容: ```yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/rewrite-target: / name: example-ingress-tomcat namespace: demo-space spec: rules: - host: "tomcat.example.com" http: paths: - backend: serviceName: tomcat-cluster-ip-svc servicePort: 8080 path: /webapp ``` #### 访问Tomcat服务 最后一步就是确认所有组件都正常运行并且能够成功响应来自客户端发起的网络请求了。确保本地hosts文件已正确映射域名指向任一worker node IP地址即可尝试打开浏览器输入URL `http://tomcat.example.com/webapp` 进行浏览体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值