如何通过 NGINX Ingress Controller 公开端口 22?

Ral*_*lph 8 nginx kubernetes

我有一个带有 NGINX 入口控制器的 Kubernetes 集群。在集群中我部署了一个Gitea POD。Web UI 和 HTTPS 访问通过 Ingress 对象公开,如下所示:

---
kind: Service
apiVersion: v1
metadata:
  name: gitea-service
  namespace: gitea-repo
spec:
  selector:
    app: gitea
  ports:
  - name: gitea-http
    port: 3000
  - name: gitea-ssh
    port: 22
---
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
  name: git-tls
  namespace: gitea-repo
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
  - hosts:
    - git.foo.com
    secretName: tls-gitea
  rules:
  - host: git.foo.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: gitea-service
            port:
              number: 3000
Run Code Online (Sandbox Code Playgroud)

这对于 HTTPS 来说一切正常。

但 Gitea 还通过端口 22 提供 SSH 访问。我的问题是,如何告诉 NGINX Ingress Controller 将端口 22 也路由到我的 Pod?

据我所知,我应该用类似的东西修补我的 NGINX 控制器部署:

spec:
  template:
    spec:
      containers:
      - name: controller
        # defind cusotm tcp/udp configmap
        args:
        - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-configmap-giteassh

        ports:
         - name: ssh
           containerPort: 22
           protocol: TCP
Run Code Online (Sandbox Code Playgroud)

并提供指向我的 gitea 服务的配置映射:

apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-configmap-giteassh
  namespace: ingress-nginx
data:
  22: "gitea-repo/gitea-service:22"
Run Code Online (Sandbox Code Playgroud)

我现在还需要在 Gitea POD 中进行额外的 Ingress 配置吗?

我想知道这是否是正确的方法。为什么我被迫在 NGINX 控制器中定义它,而不是像在 HTTP 中那样在 POD 命名空间中定义它?这意味着对于每个暴露 HTTP 之外的 TCP 端口的 POD,我必须调整我的 Ingress NGINX 控制器?

mat*_*t_j 7

我决定通过添加更多细节和解释来改进我的答案。
我找到了您的博客文章,其中包含重现此问题所需的所有信息。

在您的示例中,您需要TCP 流量通过端口22(这是 TCP 协议)。
NGINX Ingress Controller 不支持 TCP 协议,因此需要额外的配置,可以在文档中找到。
您可以按照以下步骤公开TCP服务:

  1. ConfigMap使用指定的 TCP 服务配置创建一个。
  2. --tcp-services-configmap标志添加到 Ingress 控制器配置中。
  3. 公开为 Ingress 定义的22端口。Service

Ad 1.我们需要创建一个,ConfigMap其中的键是要使用的外部端口,值是指示要公开的服务(格式为<namespace/service name>:<service port>:[PROXY]:[PROXY])。
注意:您可能需要Namespace根据 NGINX Ingress 控制器的部署位置进行更改。

$ cat ingress-nginx-tcp.yml
apiVersion: v1
kind: ConfigMap
metadata:
  name: ingress-nginx-tcp
  namespace: default  
data:
  "22": gitea-repo/gitea-service:22
Run Code Online (Sandbox Code Playgroud)

Ad 2.创建 后,我们可以使用Ingress 控制器配置中的标志ConfigMap来指向它。注意:此外,如果您想在端口定义中使用名称(例如),然后在服务的属性中引用该名称,则需要定义端口(请参阅:定义服务文档)。--tcp-services-configmap
22-tcptargetPort22

$ kubectl get deployment ingress-nginx-controller -oyaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ingress-nginx-controller
  namespace: default
spec:
...
  template:
...
    spec:
      containers:
      - args:
        - /nginx-ingress-controller
        - --tcp-services-configmap=$(POD_NAMESPACE)/ingress-nginx-tcp
...
Run Code Online (Sandbox Code Playgroud)

Ad 3.然后我们需要22在为 Ingress 定义的 Service 中公开端口。

$ kubectl get svc -oyaml ingress-nginx-controller
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-controller
  namespace: default
spec:
  ports:
  - name: 22-tcp
    nodePort: 30957
    port: 22
    protocol: TCP
    targetPort: 22
...
  type: LoadBalancer
...
Run Code Online (Sandbox Code Playgroud)

最后,我们可以通过在命令行上创建一个新的存储库来检查它是否按预期工作:
注意:我们需要有一个 gitea 用户,并具有与此帐户关联的正确 SSH 密钥。

$ git add README.md
$ git commit -m "first commit"
[master (root-commit) c6fa042] first commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README.md
$ git remote add origin git@<PUBLIC_IP>:<USERNAME>/repository.git
$ git push -u origin master
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 211 bytes | 211.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: . Processing 1 references
remote: Processed 1 references in total
To <PUBLIC_IP>:<USERNAME>/repository.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
Run Code Online (Sandbox Code Playgroud)

此外,我们可以登录 NGINX Ingress Controller Pod 并检查它是否正在侦听端口22

$ kubectl exec -it ingress-nginx-controller-784d4c9d9-jhvnm -- bash
bash-5.1$ netstat -tulpn | grep 22
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 :::22                   :::*                    LISTEN      -
Run Code Online (Sandbox Code Playgroud)