K8s进阶之外部访问Pod的几种方式

笔记哥 / 05-17 / 35点赞 / 0评论 / 612阅读
## 概述 K8s集群内部的Pod默认是不对外提供访问,只能在集群内部进行访问。这样做是为什么呢? - 安全性考虑 Kubernetes设计时遵循最小权限原则,即组件仅获得完成其任务所需的最少权限。直接暴露Pod给外部网络可能会引入安全隐患,比如让攻击者更容易定位和攻击运行在Pod内的服务。通过限制Pod的直接访问,Kubernetes鼓励使用更安全的服务暴露机制。 - 可管理性和弹性 Kubernetes设计鼓励使用Service来抽象Pod的访问。Service为一组具有相同功能的Pod提供一个稳定的服务访问入口,并且可以实现负载均衡。即使Pod因为故障重建或扩展,Service依然能够透明地路由流量到新的或现有的Pod实例,从而保证服务的高可用性和弹性。 外部要访问集群内部的Pod常用的有以下几种方式: - hostNetwork:直接使用宿主机网络的方式 - HostPort:在 Pod 定义中直接将容器端口映射到宿主机端口,绕过 Service 层,外部可通过 `节点 IP + HostPort` 直接访问 Pod。 - port-forward:用于在本地计算机和集群内运行的Pod之间建立临时的网络连接,实现端口转发。通常用于开发或者测试 - service:通过service的nodePort来进行访问 - ingress:通过ingress来进行访问,类似nginx ## HostNetwork方式 这种方式通常用于开发、测试环境,不推荐生产环境使用。 直接使用宿主机网络的方式,使用方式如下: `hostNetwork ` 是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络 使用hostNetwork方式不要使用deploy部署的方式,这样会导致所有的Pod的端口都被占用 推荐使用Pod部署的方式 示例: ```csharp # 定义deploy文件 [root@master01 ~/deploy]# cat deploy-tomcat.yaml apiVersion: apps/v1 kind: Deployment metadata: name: deployment-tomcat namespace: default spec: # 定义更新策略 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 1 replicas: 10 selector: matchLabels: app: tomcat template: metadata: name: pod-tomcat labels: app: tomcat spec: # 使用hostNetwork的方式暴漏端口访问方式 hostNetwork: true containers: - name: container-tomcat image: tomcat:9.0 restartPolicy: Always # 创建 [root@master01 ~/deploy]# kubectl apply -f deploy-tomcat.yaml deployment.apps/deployment-tomcat created ``` #### 查看Pod的启动状态 ```csharp [root@master01 ~/deploy]# kubectl get po -o wide | grep deployment-tomcat deployment-tomcat-577bcdbddc-5xvpl 0/1 CrashLoopBackOff 2 (27s ago) 56s 10.0.0.31 node01 deployment-tomcat-577bcdbddc-c7mbs 0/1 CrashLoopBackOff 2 (21s ago) 56s 10.0.0.32 node02 deployment-tomcat-577bcdbddc-dn7qb 0/1 CrashLoopBackOff 2 (21s ago) 56s 10.0.0.31 node01 deployment-tomcat-577bcdbddc-ffp4f 0/1 CrashLoopBackOff 2 (21s ago) 56s 10.0.0.31 node01 deployment-tomcat-577bcdbddc-fpsb5 1/1 Running 0 56s 10.0.0.31 node01 deployment-tomcat-577bcdbddc-gj9wg 1/1 Running 0 56s 10.0.0.32 node02 deployment-tomcat-577bcdbddc-jnvg5 0/1 CrashLoopBackOff 2 (27s ago) 56s 10.0.0.32 node02 deployment-tomcat-577bcdbddc-qsxhj 0/1 CrashLoopBackOff 2 (21s ago) 56s 10.0.0.32 node02 deployment-tomcat-577bcdbddc-swts5 0/1 CrashLoopBackOff 2 (21s ago) 56s 10.0.0.31 node01 deployment-tomcat-577bcdbddc-x6lb2 0/1 CrashLoopBackOff 2 (21s ago) 56s 10.0.0.32 node02 ``` 这里有很多Pod未启动成功,即使启动成功了也访问不了,为什么呢? 查看一下日志,发现是对应的端口被占用了,我们上面提到过,hostNetwork是使用宿主机的网络,也会使用宿主机的端口,所以当Pod调度过去之后端口被其它的Pod占用了 那么为什么启动的Pod也访问不了呢?因为deploy部署的时候所有的Pod都是同时创建的,都去争抢宿主机的端口,这就导致谁也抢不到需要绑定的端口 ```csharp [root@master01 ~/deploy]# kubectl logs -f deployment-tomcat-577bcdbddc-qsxhj 16-May-2025 15:46:31.134 SEVERE [main] org.apache.catalina.core.StandardServer.await Failed to create server shutdown socket on address [localhost] and port [8005] (base port [8005] and offset [0]) java.net.BindException: Address already in use at java.base/sun.nio.ch.Net.bind0(Native Method) at java.base/sun.nio.ch.Net.bind(Net.java:565) at java.base/sun.nio.ch.Net.bind(Net.java:554) at java.base/sun.nio.ch.NioSocketImpl.bind(NioSocketImpl.java:636) at java.base/java.net.ServerSocket.bind(ServerSocket.java:391) at java.base/java.net.ServerSocket.(ServerSocket.java:278) at org.apache.catalina.core.StandardServer.await(StandardServer.java:537) at org.apache.catalina.startup.Catalina.await(Catalina.java:829) at org.apache.catalina.startup.Catalina.start(Catalina.java:777) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:345) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:476) ``` ### 使用Pod进行部署 ```csharp [root@master01 ~/pod]# cat pod-tomcat.yaml apiVersion: v1 kind: Pod metadata: name: pod-tomcat spec: hostNetwork: true containers: - name: container-tomcat image: tomcat:latest imagePullPolicy: Always [root@master01 ~/pod]# kubectl apply -f pod-tomcat.yaml pod/pod-tomcat created # 查看pod调度到哪个节点 [root@master01 ~/pod]# kubectl get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-tomcat 1/1 Running 0 7s 10.0.0.32 node02 ``` ### 访问一下 查看Pod调度到哪个节点上,用节点IP进行访问,例如我使用10.0.0.32节点的IP进行访问 ```csharp # 验证端口是否存在,tomcat端口为8080 [root@node02 ~]# ss -lntup | grep 8080 tcp LISTEN 0 100 *:8080 *:* users:(("java",pid=2141262,fd=44)) # 在master节点进行curl访问 [root@master01 ~/pod]# curl 10.0.0.32:8080 HTTP Status 404 – Not Found... ``` ## HostPort 在 Pod 定义中直接将容器端口映射到宿主机端口,绕过 Service 层,外部可通过 `节点 IP + HostPort` 直接访问 Pod。 **这种方式在k8s v1.23.17+版本之后不会有端口监听,是采用iptables来进行转发规则。** 示例: ```csharp # 定义资源文件 [root@master01 ~/pod]# cat pod-tomcat.yaml apiVersion: v1 kind: Pod metadata: name: pod-tomcat spec: containers: - name: container-tomcat image: tomcat:latest imagePullPolicy: Always ports: - name: http # 容器的端口 containerPort: 8080 # 映射到宿主机的端口 hostPort: 8080 # 指定端口协议 protocol: TCP # 创建Pod [root@master01 ~/pod]# kubectl apply -f pod-tomcat.yaml pod/pod-tomcat created ``` ### 访问测试 ```csharp # 查看Pod调度到哪个节点 [root@master01 ~/pod]# kubectl get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-tomcat 1/1 Running 0 28s 100.95.185.255 node02 # 通过分配的IP进行访问 [root@master01 ~/pod]# curl 100.95.185.255:8080 HTTP Status 404 – Not Found... # 通过宿主机IP进行访问 [root@master01 ~/pod]# curl 10.0.0.32:8080 HTTP Status 404 – Not Found... ``` ## port-forward方式 `kubectl port-forward `是 Kubernetes 命令行工具 (kubectl) 提供的一个功能,用于在本地计算机和集群内运行的Pod之间建立临时的网络连接,实现端口转发。通常用于开发或者测试 ### 基本语法 ```csharp kubectl port-forward POD [LOCAL_PORT:]REMOTE_PORT [-n NAMESPACE] --address IP地址 --pod-running-timeout 300 ``` 参数解析: - POD: 需要转发端口的Pod的名称或标签选择器。 - LOCAL\_PORT: 本地计算机上的端口号,可选。如果不指定,Kubernetes会随机选择一个可用的本地端口。 - REMOTE\_PORT: Pod中需要转发的端口号。 - -n NAMESPACE: 指定Pod所在的命名空间,如果不在当前上下文中,则需要指定。 - --address:指定外部访问的地址 - --pod-running-timeout: 参数设置等待Pod运行的最长时间,超过这个时间命令会退出 ### 示例 ```csharp # 创建deploy [root@master01 ~/deploy]# cat deploy-tomcat.yaml apiVersion: apps/v1 kind: Deployment metadata: name: deployment-tomcat namespace: default spec: # 定义更新策略 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 1 replicas: 3 selector: matchLabels: app: tomcat template: metadata: name: pod-tomcat labels: app: tomcat spec: containers: - name: container-tomcat image: tomcat:9.0 restartPolicy: Always [root@master01 ~/deploy]# kubectl apply -f deploy-tomcat.yaml deployment.apps/deployment-tomcat created ``` 进行port-forward ```csharp [root@master01 ~/deploy]# kubectl port-forward deployment-tomcat-7ddf96c4d8-mgqzf 8080:8080 --address 0.0.0.0 Forwarding from 0.0.0.0:8080 -> 8080 ``` 访问测试 ```csharp # curl访问 [root@node01 ~]# curl 10.0.0.30:8080 HTTP Status 404 – Not Found ``` 浏览器访问,这里404只是表示没有资源,但是访问成功了 ![image](https://cdn.res.knowhub.vip/c/2505/18/d93ef351.png?G1cAAOTcVkxwP4e2iOF0Q2CDZsAijaBSwnq956x9A3x%2fMLLmZ7Q%2bY3%2f4TeszQLTUWh0Y2dCQAjmiODG5JhItl7C55jUC) ## service的方式 service有两种方式可以将Pod对外提供访问,分别是NodePort和Loadbanlacer NodePort可以看这篇文章:[K8s新手系列之Service资源](https://www.cnblogs.com/huangSir-devops/p/18859122 "K8s新手系列之Service资源") Loadbanlacer可以看这篇文章:[K8s进阶之MetalLB实现LoadBalancer](https://www.cnblogs.com/huangSir-devops/p/18876710 "K8s进阶之MetalLB实现LoadBalancer") ## ingress的方式(生产环境推荐!!!) Ingress相当于一个7层的负载均衡器,是kubernetes对反向代理的一个抽象,它的工作原理类似于Nginx,可以理解成在Ingress里建立诸多映射规则,Ingress Controller通过监听这些配置规则并转化成Nginx的反向代理配置 , 然后对外部提供服务 </div> <link href="/planet-markdown.min/planet-markdown.min.css" rel="stylesheet" /> <script src="/lib/marked/marked.min.js"></script> <script> window.onload = () => { var content = document.querySelector('.markdown-body') content.innerHTML = marked.parse(content.innerHTML.trim()) } </script> </div> <div class="alert alert-dark" role="alert">本文来自投稿,不代表本站立场,如若转载,请注明出处:http//www.knowhub.vip/share/2/3471</div> </div> <div class="shadow-sm p-3 mb-3 bg-white rounded detail-extion"> <div class="row"> <div class="col-md-6"> <div class="detail-extion-item" style="background-image:url('https://cdn.res.knowhub.vip:443//c//2505//18/dece82c1.png?G1UAAGQ9PS%2falrb4Tju6JYaEZqAijaBSz3q99%2b7TAL7fGTnHZ%2fax%2fHz4RR%2fLQYtoMmBkQUEIZFSpclazQKaaJRWscU8H')"> <a href="/share/2/3469"> <div class="detail-extion-item-title"> <span class="text-truncate">uni-app小程序登录后并跳回访问页面</span> </div> <div class="detail-extion-item-info"> <span class="pull-left">« 上一篇</span> <span class="pull-right">05-17</span> </div> </a> </div> </div> <div class="col-md-6"> <div class="detail-extion-item" style="background-image:url('https://cdn.res.knowhub.vip:443//c//2505//18/e6bb1120.png?G1QAAMTsdJxIvKSi26hD2jvFHc2ARBVBpZ71es9Z%2byb6fgdD4jNan74%2f%2fKH16XQZhAuBoawIPlmCAlmqBBUUMdMa13A%3d')"> <a href="/share/2/3483"> <div class="detail-extion-item-title"> <span class="text-truncate">ArkUI-X跨平台框架接入指南</span> </div> <div class="detail-extion-item-info"> <span class="pull-right">05-18</span> <span class="pull-left">下一篇 »</span> </div> </a> </div> </div> </div> </div> <img src="/Detail/Visits/3471" alt="" class="none-img" /> </div> <div class="col-sm-12 col-md-3" style="padding:0 5px"> <div> <ul class="list-group list-group-flush list-ls"> <li class="list-group-item list-hot-title font-weight-bold">热门的技术博文分享</li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/3654" target="_blank"> <i>1</i> <span>.</span> <span>ESP实现Web服务器</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/3308" target="_blank"> <i>2</i> <span>.</span> <span>从零到一:打造高效的金仓社区 API 集成到 MCP 服务方案</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/3166" target="_blank"> <i>3</i> <span>.</span> <span>使用C#构建一个同时问多个LLM并总结的小工具</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/2944" target="_blank"> <i>4</i> <span>.</span> <span>.NET 原生驾驭 AI 新基建实战系列Milvus ── 大规模 AI 应用的向量数据库首选</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/2452" target="_blank"> <i>5</i> <span>.</span> <span>在Avalonia/C#中使用依赖注入过程记录</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/2020" target="_blank"> <i>6</i> <span>.</span> <span> [设计模式/Java] 设计模式之工厂方法模式</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/2002" target="_blank"> <i>7</i> <span>.</span> <span>5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明 </span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/864" target="_blank"> <i>8</i> <span>.</span> <span>SQL 中的各种连接 JOIN 的区别总结! </span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/3018" target="_blank"> <i>9</i> <span>.</span> <span>JavaScript 中防抖和节流的多种实现方式及应用场景</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/2697" target="_blank"> <i>10</i> <span>.</span> <span>SaltStack 远程命令执行中文乱码问题</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/2673" target="_blank"> <i>11</i> <span>.</span> <span>推荐10个 DeepSeek 神级提示词,建议搜藏起来使用</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/2565" target="_blank"> <i>12</i> <span>.</span> <span>C#基础:枚举、数组、类型、函数等解析</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/2288" target="_blank"> <i>13</i> <span>.</span> <span>VMware平台的Ubuntu部署完全分布式Hadoop环境</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/2155" target="_blank"> <i>14</i> <span>.</span> <span>C# 多项目打包时如何将项目引用转为包依赖 </span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/2153" target="_blank"> <i>15</i> <span>.</span> <span>Chrome 135 版本开发者工具(DevTools)更新内容</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/1878" target="_blank"> <i>16</i> <span>.</span> <span>从零创建npm依赖,只需执行一条命令</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/3677" target="_blank"> <i>17</i> <span>.</span> <span>关于 Newtonsoft.Json 和 System.Text.Json 混用导致的的序列化不识别的问题</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/3424" target="_blank"> <i>18</i> <span>.</span> <span>大模型微调实战之训练数据集准备的艺术与科学</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/3277" target="_blank"> <i>19</i> <span>.</span> <span>Windows快速安装MongoDB之Mongo实战</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/3114" target="_blank"> <i>20</i> <span>.</span> <span>探索 C# 14 新功能:实用特性为编程带来便利</span> </a> </li> </ul> </div> <div class="gap"></div> <div> <ul class="list-group list-group-flush list-ls"> <li class="list-group-item list-hot-title font-weight-bold">相关联分享</li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/3897" target="_blank"> <span>Pod调度之亲和性</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/3436" target="_blank"> <span>K8stools工具</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/3874" target="_blank"> <span>K8s集群中的DNS服务(CoreDNS)详解</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/3907" target="_blank"> <span>K8s新手系列之指定Pod调度到指定节点上</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/3471" target="_blank"> <span>K8s进阶之外部访问Pod的几种方式</span> </a> </li> <li class="list-group-item text-truncate"> <a class="bd-highlight" href="/share/2/3884" target="_blank"> <span>K8s新手系列之探针</span> </a> </li> </ul> </div> </div> </div> <div class="row"> </div> </main> </div> <footer class="border-top footer text-muted"> <div class="container"> <div> 备案号: <a href="http://beian.miit.gov.cn">蜀 - 12365458号</a>    联系邮箱: <a href="mail://123456@qq.com">123456@qq.com</a>    </div> <div> 版权声明: <span>Copyright 2024- 2026 www.hthcms.com Inc. All Rights Reserved. [HTHCMS]</span> © 2025 - <a href="www.knowhub.vip">资源分享网 </a> </div> </div> </footer> <link href="/lib/bootstrap/dist/css/bootstrap-icons.css" rel="stylesheet" /> <script src="/lib/jquery/dist/jquery.min.js"></script> <script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="/lib/moment/moment.min.js"></script> <script src="/lib/numeral/numeral.min.js"></script> <script src="/js/site.js?v=_Gn9lwJUAA1Nk6QxtNWyl-yt-FkDLbyiBgCcbq2HAs8"></script> <!--统计代码--> <script>var tj='统计代码';console.log(tj)</script> </body> </html>