自建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 查询 80、443 # 分别查 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

保存退出后,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 #新增

保存退出后,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
如果访问不通,云服务器安全组端口放行

五,清理无用 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及域名访问。

浙公网安备 33010602011771号