概述
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部署的方式
示例:- # 定义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的启动状态
- [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 <none> <none>
- deployment-tomcat-577bcdbddc-c7mbs 0/1 CrashLoopBackOff 2 (21s ago) 56s 10.0.0.32 node02 <none> <none>
- deployment-tomcat-577bcdbddc-dn7qb 0/1 CrashLoopBackOff 2 (21s ago) 56s 10.0.0.31 node01 <none> <none>
- deployment-tomcat-577bcdbddc-ffp4f 0/1 CrashLoopBackOff 2 (21s ago) 56s 10.0.0.31 node01 <none> <none>
- deployment-tomcat-577bcdbddc-fpsb5 1/1 Running 0 56s 10.0.0.31 node01 <none> <none>
- deployment-tomcat-577bcdbddc-gj9wg 1/1 Running 0 56s 10.0.0.32 node02 <none> <none>
- deployment-tomcat-577bcdbddc-jnvg5 0/1 CrashLoopBackOff 2 (27s ago) 56s 10.0.0.32 node02 <none> <none>
- deployment-tomcat-577bcdbddc-qsxhj 0/1 CrashLoopBackOff 2 (21s ago) 56s 10.0.0.32 node02 <none> <none>
- deployment-tomcat-577bcdbddc-swts5 0/1 CrashLoopBackOff 2 (21s ago) 56s 10.0.0.31 node01 <none> <none>
- deployment-tomcat-577bcdbddc-x6lb2 0/1 CrashLoopBackOff 2 (21s ago) 56s 10.0.0.32 node02 <none> <none>
复制代码 这里有很多Pod未启动成功,即使启动成功了也访问不了,为什么呢?
查看一下日志,发现是对应的端口被占用了,我们上面提到过,hostNetwork是利用宿主机的网络,也会利用宿主机的端口,所以当Pod调度过去之后端口被其它的Pod占用了
那么为什么启动的Pod也访问不了呢?因为deploy部署的时间全部的Pod都是同时创建的,都去争抢宿主机的端口,这就导致谁也抢不到需要绑定的端口- [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.<init>(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进行部署
- [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 <none> <none>
复制代码 访问一下
查看Pod调度到哪个节点上,用节点IP进行访问,例如我利用10.0.0.32节点的IP进行访问- # 验证端口是否存在,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
- <!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title>...
复制代码 HostPort
在 Pod 定义中直接将容器端口映射到宿主机端口,绕过 Service 层,外部可通过 节点 IP + HostPort 直接访问 Pod。
这种方式在k8s v1.23.17+版本之后不会有端口监听,是采用iptables来进行转发规则。
示例:- # 定义资源文件
- [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
复制代码 访问测试
- # 查看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 <none> <none>
- # 通过分配的IP进行访问
- [root@master01 ~/pod]# curl 100.95.185.255:8080
- <!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title>...
- # 通过宿主机IP进行访问
- [root@master01 ~/pod]# curl 10.0.0.32:8080
- <!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title>...
复制代码 port-forward方式
kubectl port-forward 是 Kubernetes 命令行工具 (kubectl) 提供的一个功能,用于在本地计算机和集群内运行的Pod之间创建临时的网络连接,实现端口转发。通常用于开发或者测试
基本语法
- 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运行的最长时间,超过这个时间命令会退出
示例
- # 创建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- [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
复制代码 访问测试- # curl访问
- [root@node01 ~]# curl 10.0.0.30:8080
- <!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found
复制代码 浏览器访问,这里404只是表示没有资源,但是访问成功了
service的方式
service有两种方式可以将Pod对外提供访问,分别是NodePort和Loadbanlacer
NodePort可以看这篇文章:K8s新手系列之Service资源
Loadbanlacer可以看这篇文章:K8s进阶之MetalLB实现LoadBalancer
ingress的方式(生产环境推荐!!!)
Ingress相称于一个7层的负载平衡器,是kubernetes对反向代理的一个抽象,它的工作原理雷同于Nginx,可以理解成在Ingress里创建诸多映射规则,Ingress Controller通过监听这些设置规则并转化成Nginx的反向代理设置 , 然后对外部提供服务
可以参考这篇文章:K8s进阶之初识Ingress
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |