如何通过NGINX入口控制器暴露端口22 ?



我有一个带有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

但是Gitea也通过端口22提供SSH访问。我的问题是,我怎么能告诉NGINX入口控制器路由也端口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

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

apiVersion: v1
kind: ConfigMap
metadata:
name: tcp-configmap-giteassh
namespace: ingress-nginx
data:
22: "gitea-repo/gitea-service:22"

我现在还需要在我的Gitea POD中添加一个额外的入口配置吗?

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

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

在您的示例中,您需要TCP流量通过端口22(它是TCP协议)。
NGINX入口控制器不支持TCP协议,所以额外的配置是必要的,可以在文档中找到。
您可以按照以下步骤公开TCP服务:

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

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

$ cat ingress-nginx-tcp.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: ingress-nginx-tcp
namespace: default  
data:
"22": gitea-repo/gitea-service:22

广告2。创建ConfigMap之后,我们可以在Ingress控制器配置中使用--tcp-services-configmap标志指向它。
注意:另外,如果你想在端口定义中使用一个名称(例如22-tcp),然后在服务的targetPort属性中引用这个名称,你需要定义端口22(参见:定义服务文档)。

$ 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
...

广告3。然后我们需要在为入口定义的服务中公开端口22

$ 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
...

最后,我们可以通过在命令行上创建一个新的存储库来检查它是否按预期工作:
注意:我们需要有一个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'.

此外,我们可以登录到NGINX入口控制器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      -

最新更新