<p>I have a Kubernetes Cluster with a NGINX Ingress Controller. In the cluster I have deployed a <a href="https://gitea.io/" rel="noreferrer">Gitea</a> POD. The Web UI and the HTTPS access is exposed via an Ingress object like this one:</p>
<pre><code>---
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: &quot;letsencrypt-prod&quot;
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
</code></pre>
<p>This works all fine for HTTPS.</p>
<p>But Gitea also provides a SSH access through port 22. My Question is, how can I tell the NGINX Ingress Controller to route also port 22 to my pod?</p>
<p>As far as I understand I should patch my NGINX controller deployment with something like that:</p>
<pre><code>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
</code></pre>
<p>and providing a config map pointing to my gitea service:</p>
<pre><code>apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-configmap-giteassh
  namespace: ingress-nginx
data:
  22: &quot;gitea-repo/gitea-service:22&quot;
</code></pre>
<p>Do I need also an additional Ingress configuration in my Gitea POD now?</p>
<p>I wonder if this is the correct approach. Why I am forced to define this in the NGINX controller and not in my POD namespace as I do for HTTP? This would mean that for each POD exposing a TCP port other than HTTP I have to adjust my Ingress NGINX Controller?</p>

<p>I decided to improve my answer by adding more details and explanations.<br />
I found your <a href="https://ralph.blog.imixs.com/2021/02/25/running-gitea-on-kubernetes/" rel="noreferrer">blog post</a> which contains all the information I need to reproduce this problem.</p>
<p>In your example you need <strong>TCP traffic</strong> to pass through on port <code>22</code> (it is TCP protocol).<br />
NGINX Ingress Controller doesn't support TCP protocol, so additional configuration is necessary, which can be found in the <a href="https://ralph.blog.imixs.com/2021/02/25/running-gitea-on-kubernetes/" rel="noreferrer">documentation</a>.<br />
You can follow the steps below to expose the TCP service:</p>
<ol>
<li>Create a <code>ConfigMap</code> with the specified TCP service configuration.</li>
<li>Add the <code>--tcp-services-configmap</code> flag to the Ingress controller configuration.</li>
<li>Expose port <code>22</code> in the <code>Service</code> defined for the Ingress.</li>
</ol>
<hr />
<p><em>Ad 1.</em> We need to create a <code>ConfigMap</code> with the key that is the external port to use and the value that indicates the service to expose (in the format <code>&lt;namespace/service name&gt;:&lt;service port&gt;:[PROXY]:[PROXY]</code>).<br />
<strong>NOTE:</strong> You may need to change <code>Namespace</code> depending on where the NGINX Ingress controller is deployed.</p>
<pre><code>$ cat ingress-nginx-tcp.yml
apiVersion: v1
kind: ConfigMap
metadata:
  name: ingress-nginx-tcp
  namespace: default  
data:
  &quot;22&quot;: gitea-repo/gitea-service:22
</code></pre>
<p><em>Ad 2.</em> After creating the <code>ConfigMap</code>, we can point to it using the <code>--tcp-services-configmap</code> flag in the Ingress controller configuration.<br />
<strong>NOTE:</strong> Additionally, if you want to use a name (e.g. <code>22-tcp</code>) in the port definition and then reference this name in the <code>targetPort</code> attribute of a Service, you need to define port <code>22</code> (see: <a href="https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service" rel="noreferrer">Defining a Service</a> documentation).</p>
<pre><code>$ 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
...
</code></pre>
<p><em>Ad 3.</em> Then we need to expose port <code>22</code> in the Service defined for the Ingress.</p>
<pre><code>$ 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
...
</code></pre>
<p>Finally, we can check if it works as expected by creating a new repository on the command line:<br />
<strong>Note:</strong> We need to have a gitea user with the proper SSH keys associated with this account.</p>
<pre><code>$ git add README.md
$ git commit -m &quot;first commit&quot;
[master (root-commit) c6fa042] first commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README.md
$ git remote add origin git@&lt;PUBLIC_IP&gt;:&lt;USERNAME&gt;/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 &lt;PUBLIC_IP&gt;:&lt;USERNAME&gt;/repository.git
 * [new branch]      master -&gt; master
Branch 'master' set up to track remote branch 'master' from 'origin'.
</code></pre>
<p>In addition, we can log to the NGINX Ingress Controller Pod and check if it is listening on port <code>22</code>:</p>
<pre><code>$ 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      -
</code></pre>
