自建k8s集群,ingress使用hostPort或hostNetwork模式绑定缩主机网络,暴露对外的访问端口为80端口

如果让ingress通过域名或服务器公网ip对外访问,需要创建NodePort类型的ingress规则,然后在浏览器里通过http://公网ip:30080 或 https://公网ip:30443 这种方式访问,后面必须要带一个30000到32767之间的端口,如何让ingress不带端口访问呢,像普通域名一样不需要带端口访问呢?

解决方案是,使用 hostNetwork 模式,直接监听宿主机的80 / 443 端口。

 

步骤:

一、前置校验(避免端口占用失败)

1)关闭宿主机占用 80/443 的服务

# ubuntu/debian
systemctl stop nginx apache2
systemctl disable nginx apache2

 

2)防火墙放行端口

ufw allow 80/tcp
ufw allow 443/tcp

 

3)验证端口监听

80 / 443 端口占用会导致修改后ingress pod运行失败,一定要停掉占用端口的服务。

# Ubuntu/Debian
apt update && apt install lsof -y

# CentOS 7/8/9
yum install lsof -y

查询 80443
# 分别查
lsof -i :80
lsof -i :443

# 一条命令同时查80、443
lsof -i :80 -i :443

 

有输出 = 端口被占用;无输出 = 空闲

 

二、修改 Deployment 开启宿主机 80/443 端口

【方案一:使用hostPort,推荐】

1、先备份原有配置(必做)

kubectl get deploy ingress-nginx-controller -n ingress-nginx -o yaml > ingress-controller-bak.yaml

  

2、打开编辑器

kubectl edit deploy ingress-nginx-controller -n ingress-nginx

 如果ingress-nginx控制器是用deamonset部署的,命令改成: kubectl edit daemonset ingress-nginx-controller -n ingress-nginx

 

3,新增两个hostPort端口

找到 spec.template.spec.containers.ports 这一层,当前内容:

spec:
  template:
    spec:
      containers:
      - args:
        ...省略...
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        - containerPort: 443
          name: https
          protocol: TCP
        - containerPort: 8443
          name: webhook
          protocol: TCP
        ...省略...
      dnsPolicy: ClusterFirst

 

改两个地方:

1),在 - containerPort: 80 下面新增 hostPort: 80,

2),在 - containerPort: 443 下面新增 hostPort: 443

改完后如下:

spec:
  template:
    spec:
      containers:
      - args:
        ...省略...
        ports:
        - containerPort: 80
          hostPort: 80    #新增
          name: http
          protocol: TCP
        - containerPort: 443
          hostPort: 443   #新增
          name: https
          protocol: TCP
        - containerPort: 8443
          name: webhook
          protocol: TCP
        ...省略...
      dnsPolicy: ClusterFirst

 

image

 

 保存退出后,deployment 会自动滚动重建 Pod。

 

4,重启控制器 Pod 生效(可以跳过这一步,修改后会自动重启)

kubectl rollout restart deployment ingress-nginx-controller -n ingress-nginx

 

 

【方案二:使用hostNetwork模式】

1,先备份原有配置(必做)

kubectl get deploy ingress-nginx-controller -n ingress-nginx -o yaml > ingress-controller-bak.yaml

 

2,打开编辑器

kubectl edit deploy ingress-nginx-controller -n ingress-nginx

  如果ingress-nginx控制器是用deamonset部署的,命令改成: kubectl edit daemonset ingress-nginx-controller -n ingress-nginx

 

 3,改两个地方:

1)找到 spec.template.spec.dnsPolicy,把dnsPolicy的值由 ClusterFirst 改成 ClusterFirstWithHostNet,

2)在dnsPolicy的平级新增 hostNetwork: true

改完后:

spec:
  template:
    spec:
      containers:
      - args:
        ...省略...
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        - containerPort: 443
          name: https
          protocol: TCP
        - containerPort: 8443
          name: webhook
          protocol: TCP
        ...省略...
      dnsPolicy: ClusterFirstWithHostNet #由ClusterFirst 改成 ClusterFirstWithHostNet
      hostNetWork: true   #新增

 

image

  

 保存退出后,deployment 会自动滚动重建 Pod。

 

4,重启控制器 Pod 生效(可以跳过这一步,修改后会自动重启)

kubectl rollout restart deployment ingress-nginx-controller -n ingress-nginx
或
kubectl rollout restart daemonset ingress-nginx-controller -n ingress-nginx

 

三、验证 Pod 是否启用 hostNetwork

kubectl get pods -n ingress-nginx -o yaml | grep hostNetwork

 

输出 hostNetwork: true 代表配置生效


四,测试不带端口访问

更改之前(带端口)

http://公网ip或域名:30080/v1
https://公网ip或域名:30443/v1

 

更改之后(不带端口 )

http://公网ip或域名/v1
https://公网ip或域名/v1

 

如果访问不通,云服务器安全组端口放行

image

五,清理无用 NodePort Service(可选,可以不用删) 

kubectl delete svc ingress-nginx-controller -n ingress-nginx

 

六,注意,这两种方式都会有坑

每个节点只有一个pod才能占用 80 / 443端口。

Deployment,多个pod调度到同一节点,只有一个pod会Running成功,其它pod会Running失败。只有调度到的节点才可以通过 ip及域名访问。

Daemonset,每个节点有一个pod会调度成功,其它Daeonset用 80 / 443 端口调度会Running失败。只有调度成功的pod才可以通过 ip及域名访问。

 

posted @ 2026-07-25 17:11  民工黑猫  阅读(30)  评论(0)    收藏  举报