一、DaemonSet
1.概述
目标:是在集群的每个节点上运行且仅运行一个 Pod
应用场景:
- 网络代理(如 kube-proxy):必须每个节点都运行一个 Pod,否则节点就无法加入Kubernetes 网络
- 监控应用(如 node-exporter):必须每个节点都有一个 Pod 用来监控节点的状态,实时上报信息
- 日志采集(如 filebeat):必须在每个节点上运行一个 Pod,才能够搜集容器运行时产生的日志数据
- 安全应用:每个节点都要有一个 Pod 来执行安全审计、入侵检查、漏洞扫描等工作
2.YAML 模版
(1)基本信息
[root@localhost ~]# kubectl api-resources | grep DaemonSet
daemonsets ds apps/v1 true DaemonSet
(2)配置模版
[root@localhost 09-daemonset]# cat node-exporter-ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter-ds
labels:
app: node-exporter
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
containers:
- name: node-exporter
image: registry.cn-beijing.aliyuncs.com/xxhf/node-exporter:1.6.1
resources:
limits:
cpu: 200m
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
3.DaemonSet&&Deployment

注:DaemonSet 在 spec 里没有 replicas 字段
4.部署 DaemonSet
我们执行命令 kubectl apply 来创建 DaemonSet 对象,再用 kubectl get 查看对象的状态:
[root@localhost 09-daemonset]# kubectl apply -f node-exporter-ds.yaml
daemonset.apps/node-exporter-ds created
[root@localhost 09-daemonset]# kubectl get ds
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
node-exporter-ds 2 2 1 2 1 <none> 21s
[root@localhost 09-daemonset]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
worker Ready <none> 5d21h v1.32.2
master Ready control-plane 5d21h v1.32.2
[root@localhost 09-daemonset]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
node-exporter-ds-th66g 1/1 Running 0 51s 172.17.20.10 worker <none> <none>
node-exporter-ds-xf69n 1/1 Running 0 51s 172.17.219.113 master <none> <none>
- 虽然我们没有指定 DaemonSet 里 Pod 要运行的数量,但它自己就会去查找集群里的节点,在节点里创建 Pod
- 因为环境里有一个 Master 一个 Worker,所以 DaemonSet 在每个节点生成一个 Pod
- master 有 taint 污点 ,会阻止 Pod 被 调度到 有污点的master节点上(我这里已经清除了)
5.新增worker node
[root@localhost ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane 5d22h v1.32.2
worker Ready <none> 87s v1.32.2
worker2 Ready <none> 8m1s v1.32.2
[root@localhost ~]# kubectl get ds
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
node-exporter-ds 3 3 3 3 3 <none> 31m
[root@localhost ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
node-exporter-ds-98968 1/1 Running 0 96s 172.17.20.11 worker <none> <none>
node-exporter-ds-nhxw6 1/1 Running 0 2m54s 172.17.189.65 worker2 <none> <none>
node-exporter-ds-xf69n 1/1 Running 0 32m 172.17.219.113 master <none> <none>
注:可以看到,集群中只要添加新节点,daemonset控制器就会发现并添加进来
6.静态 Pod
-
不受 Kubernetes 系统的管控
-
唯一能够管理它的 Kubernetes 组件只有在每个节点上运行的 kubelet
-
静态 Pod的 YAML 文件默认都存放在节点的 /etc/kubernetes/manifests 目录下
-
kubelet 会定期检查目录里的文件,发现变化就会调用容器运行时创建或者删除静态 Pod
[root@localhost ~]# cd /etc/kubernetes/manifests/
[root@localhost manifests]# ll
总用量 16
-rw------- 1 root root 2565 11月 14 19:54 etcd.yaml
-rw------- 1 root root 3625 11月 14 19:54 kube-apiserver.yaml
-rw------- 1 root root 3131 11月 14 19:54 kube-controller-manager.yaml
-rw------- 1 root root 1680 11月 14 19:54 kube-scheduler.yaml
注:可以看到,Kubernetes 的 4 个核心组件 apiserver、etcd、scheduler、controller-manager原来都以静态 Pod 的形式存在的,这也是为什么它们能够先于 Kubernetes 集群启动的原因
二、网络代理对象-Service
1.概述
- service:主要是在 第4层(传输层,TCP/UDP)上进行代理。它提供了在集群内部不同Pod之间进行通信的负载均衡
- ingress:在 第7层(应用层,HTTP/HTTPS)上进行代理。它是一个 HTTP 和 HTTPS 路由控制器,允许用户将外部请求路由到集群内的不同服务
2.Service主要类型

- ClusterIP(默认):为服务分配一个集群内的 IP 地址,只能在集群内部访问
- NodePort :为服务在每个节点上分配一个端口,使外部能够通过 <NodeIP>:<NodePort> 访问集群内的服务
- LoadBalancer:在云环境中使用,通过云平台的负载均衡器来公开服务,可以在外部通过负载均衡器 IP 地址访问服务
- ExternalName:将服务映射到外部的 DNS 名称,不通过代理直接访问
3.Service YAML模版
(1)查看基本信息
[root@localhost manifests]# kubectl api-resources | grep services
services svc v1 true Service
apiservices apiregistration.k8s.io/v1 false APIService
(2)创建模版:使用 kubectl expose 指令来创建service模板文件
-
需要用参数 --port 和 --target-port 分别指定映射端口和容器端口
-
Service 自己的 IP 地址和后端 Pod 的 IP 地址可以自动生成,用法上和Docker 的命令行参数 -p 很类似
[root@localhost ~]# kubectl expose deploy nginx-dep --port=80 --target-port=80 --dry-run=client -o yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: nginx-dep
name: nginx-dep
spec:
ports:
- port: 80 # svc对外暴露的端口
protocol: TCP
targetPort: 80 # 容器中应用监听的端口
selector: # 过滤代理 Pod
app: nginx-dep
status:
loadBalancer: {}
(3)图文展示

4.启动Service服务
为了方便查看 Service 的效果,我们添加一个Nginx的配置文件,使用ConfigMap来定义,通过Volume 挂载到 Pod中:
[root@localhost 10-service]# cat nginx-conf-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-conf
data:
default.conf: |
server {
listen 80;
location / {
default_type text/plain;
return 200
'srv : $server_addr:$server_port\nhost: $hostname\nuri : $request_method $host $request_uri\ndate: $time_iso8601\n';
}
}
# 在 Deployment 中通过 "template.volumes"定义存储卷,使用"volumeMounts" 挂载到容器中
[root@localhost 10-service]# cat nginx-dep.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-dep
name: nginx-dep
spec:
replicas: 2
selector:
matchLabels:
app: nginx-dep
template:
metadata:
labels:
app: nginx-dep
spec:
volumes:
- name: nginx-conf-vol
configMap:
name: nginx-conf
containers:
- image: registry.cn-beijing.aliyuncs.com/xxhf/nginx:1.22.1
name: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /etc/nginx/conf.d
name: nginx-conf-vol
部署 Deployment:
[root@localhost 10-service]# kubectl apply -f nginx-conf-cm.yaml -f nginx-dep.yaml
configmap/nginx-conf unchanged
deployment.apps/nginx-dep configured
[root@localhost 10-service]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-dep-7d666df79b-9bw4b 1/1 Running 0 3s
nginx-dep-7d666df79b-cgs4b 1/1 Running 0 1s
# 测试
[root@localhost 10-service]# curl 172.17.171.72
srv : 172.17.171.72:80
host: nginx-dep-7d666df79b-xpkb7
uri : GET 172.17.171.72 /
date: 2025-11-20T12:03:30+00:00
[root@localhost 10-service]# curl 172.17.189.71
srv : 172.17.189.71:80
host: nginx-dep-7d666df79b-cgs4b
uri : GET 172.17.189.71 /
date: 2025-11-20T12:03:35+00:00
创建 Service 对象:
[root@localhost 10-service]# cat nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx-dep
ports:
- port: 80
targetPort: 80
protocol: TCP
[root@localhost 10-service]# kubectl apply -f nginx-svc.yaml
[root@localhost 10-service]# kubectl get svc
svc 对外IP svc对外端口
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 192.168.111.1 <none> 443/TCP 6d
nginx-svc ClusterIP 192.168.111.75 <none> 80/TCP 13s
注:Kubernetes 会自动为 Service 对象分配一个IP地址,这个地址段是独立于Pod地址段的(在kubeadm 安装的配置文件里指定的)它是一个"虚地址",不存在实体,只能用来转发流量

用 curl 访问 Service 的 IP 地址(每个节点都行),就会看到它把数据转发给后端的 Pod,输出信息会显示具体是哪个 Pod 响应了请求,就表明 Service 确实完成了对 Pod 的负载均衡任务
# 查看 Service 代理了哪些后端的 Pod
[root@localhost 10-service]# kubectl describe svc
Endpoints: 172.17.189.71:80,172.17.171.72:80
[root@localhost 10-service]# kubectl api-resources | grep Endpoints
endpoints ep v1 true Endpoints
[root@localhost 10-service]# kubectl get ep
NAME ENDPOINTS AGE
kubernetes 192.168.5.110:6443 6d
nginx-svc 172.17.171.72:80,172.17.189.71:80 10m
调整副本数:
[root@localhost 10-service]# kubectl scale deployment nginx-dep --replicas 3
deployment.apps/nginx-dep scaled
[root@localhost 10-service]# kubectl get ep
NAME ENDPOINTS AGE
kubernetes 192.168.5.110:6443 6d
nginx-svc 172.17.171.72:80,172.17.189.71:80,172.17.219.115:80 12m
注:因为deployment管理的pod ip和svc的虚地址ip是不固定的(创建之后会变),所以要想办法屏蔽ip,使用域名
5.使用域名

- Kubernetes 有一个插件来实现 DNS 的功能,在早期这个插件普遍使用 kube-dns,现在用 coredns 比较多
- Service 对象的域名完全形式是 "对象名. 命名空间.svc.cluster.local",但很多时候也可以省略后面的部分,直接写"对象名. 命名空间"甚至"对象名"也可以
- DNS 是在 Kubernetes 集群内部生效,所以要测试需要在 Pod 内验证

# curl nginx-svc 转换成 IP 找DNS 服务器 192.168.111.10 svc > pod coredns
# cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 192.168.111.10
options ndots:5
# 因为有搜索域,所以使用域名访问时可以省略
注:可以看到,现在我们就不再关心 Service 对象的 IP 地址,只需要知道它的名字,就可以用DNS 的方式去访问后端服务
补充知识点:
svc-name ns-name svc 集群域名
nginx-svc. default. svc. cluster.local
# 集群域名在初始化的时候就确定了
[root@localhost ~]# vi kubeadm-config.yaml
networking:
dnsDomain: cluster.local
# 多个集群时,可以修改以区分不同集群
6.Service 对外暴露服务
- Service 是一种负载均衡技术
- 对内管理 Kubernetes 集群内部的服务
- 对外还能够向集群外部暴露服务
- Service 关键字段"type",表示 Service 是哪种类型的负载均衡

(1)NodePort
注:在集群外使用, 在集群内所有节点监听一个端口 30000 - 32767 随机 ,测试环境
我们修改一下 Service 的 YAML 文件,加上 "type" 字段:
[root@localhost 10-service]# cat nginx-svc-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx-dep
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30080
protocol: TCP
更新对象,查看状态:
[root@localhost 10-service]# kubectl apply -f nginx-svc-nodeport.yaml
service/nginx-svc configured
[root@localhost 10-service]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 192.168.111.1 <none> 443/TCP 6d1h
nginx-svc NodePort 192.168.111.75 <none> 80:30080/TCP 50m
注:多出了一个"30080"端口,这就是 Kubernetes 在节点上为 Service 创建的专用映射端口
[root@localhost 10-service]# kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master Ready control-plane 6d1h v1.32.2 192.168.5.110 <none> Rocky Linux 9.4 (Blue Onyx) 5.14.0-570.32.1.el9_6.x86_64 containerd://1.7.25
worker Ready <none> 155m v1.32.2 192.168.5.120 <none> Rocky Linux 9.4 (Blue Onyx) 5.14.0-570.32.1.el9_6.x86_64 containerd://1.7.25
worker2 Ready <none> 161m v1.32.2 192.168.5.130 <none> Rocky Linux 9.4 (Blue Onyx) 5.14.0-570.32.1.el9_6.x86_64 containerd://1.7.25
[root@localhost 10-service]# curl 192.168.5.120:30080
srv : 172.17.171.72:80
host: nginx-dep-7d666df79b-xpkb7
uri : GET 192.168.5.120 /
date: 2025-11-20T12:59:17+00:00
[root@localhost 10-service]# curl 192.168.5.130:30080
srv : 172.17.171.72:80
host: nginx-dep-7d666df79b-xpkb7
uri : GET 192.168.5.130 /
date: 2025-11-20T12:59:21+00:00
(2)ExternalName
- 使用 DNS CNAME 机制把自己 CNAME 到你指定的另外一个域名上
- 可以提供集群内的名字,比如mysql.db.svc 这样的建立在db命名空间内的 MySQL 服务
- 也可以指定 http://www.baidu.com 这样的外部真实域名
我们需要使用 ping 和nslookup 命令,所以部署一个 busybox 的 deployment:
[root@localhost 10-service]# cat busy-dep.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: busy-dep
name: busy-dep
spec:
replicas: 1
selector:
matchLabels:
app: busy-dep
template:
metadata:
labels:
app: busy-dep
spec:
containers:
- image: busybox:latest
name: busybox
command: ["/bin/sh","-c","sleep 3600"]
imagePullPolicy: IfNotPresent
[root@localhost 10-service]# kubectl apply -f busy-dep.yaml
deployment.apps/busy-dep created
创建一个 External Service:
[root@localhost 10-service]# cat external-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: external-svc
spec:
type: ExternalName
externalName: www.baidu.com
[root@localhost 10-service]# kubectl apply -f external-svc.yaml
service/external-svc created
[root@localhost 10-service]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
external-svc ExternalName <none> www.baidu.com <none> 75s
登录到 Pod 中验证 External Service:
[root@localhost 10-service]# kubectl get pod
NAME READY STATUS RESTARTS AGE
busy-dep-5cb966fd7b-4cd5s 1/1 Running 0 5s
[root@localhost 10-service]# kubectl exec -it busy-dep-5cb966fd7b-4cd5s -- sh


注:可以看到 external-svc 会被解析到一个 CNAME 指向 www.baidu.com
(3)LoadBalancer
我们修改 service 的类型为 LoadBalancer 看一下效果:
[root@localhost 10-service]# cat nginx-svc-lb.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx-dep
type: LoadBalancer
ports:
- port: 80
targetPort: 80
protocol: TCP
[root@localhost 10-service]# kubectl apply -f nginx-svc-lb.yaml

注:LoadBalancer 也是用了 NodePort 的实现方式,因为 PORT 列还保留了 NodePort 的端口
7.不同 Service 类型对比
- ClusterIP:只能在集群内部使用。clusterIP 域名
- NodePort:可以作为集群流量入口,但也有一些缺点,端口数量有限
- ExternalName: 只是一个CNAME,应用场景有限
- LoadBalancer:依赖云厂商实现。 生产环境
8.Service 的三个 port
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx-dep
type: NodePort
ports:
- port: 80 # ClusterIP
targetPort: 80 # 容器的端口
nodePort: 30080 #
protocol: TCP
Service 的几个 port 的概念很容易混淆,它们分别是 port 、 targetPort 和 NodePort :
- port 表示 Service 暴露的服务端口,也是客户端访问用的端口,例如 Cluster IP:port 是提供给集群内部客户访问 Service 的入口 。 需要注意的是, port 不仅是 Cluster IP 上暴露的端口,还可以是 external IP 和 Load Balancer IP 。 Service 的 port 并不监听在节点 IP 上,即无法通过节点 IP:port 的方式访问 Service
- NodePort 是 Kubemetes 提供给集群外部访问 Service 的入口的一种方式(另 一种方式是 Load Balancer ),所以可以通过 Node IP:nodePort 的方式提供集群外访问 Service 的入口 。 需要注意的是,我们这里说的集群外指的是 Pod 网段外,例如 Kubemetes 节点或因特网
- targetPort 很好理解,它是应用程序实际监听 Pod 内流量的端口,从 port 和 NodePort 上到来的数据,最终经过 Kube-proxy 流入后端 Pod 的 targetPort 进入容器
9.Service 实现原理
- 在 Kubernetes 集群中,每个 Node 运行一个 kube-proxy 进程
- kube-proxy 负责为 Service 实现了一种 VIP(虚拟 IP)
10.Service 底层技术
- userspace 早期的版本中使用
- iptables 默认
- IPVS SVC 比较多的场景 ,建议使用 IPVS 模式
(1)iptables
- 这种模式,kube-proxy 会监听 apiserver 对 Service 对象和 Endpoints 对象的添加和移除
- 添加上 iptables 规则,从而捕获到达该 Service 的 clusterIP(虚拟 IP)和端口的请求,进而将请求重定向到 Service 的一组 backend 中的某一个 Pod 上面
- 使用 Pod readiness 探针 验证后端 Pod 是否可以正常工作避免将流量通过 kube-proxy 发送到已知失败的 Pod 中
(2)查看 Kube-proxy 当前运行模式
[root@localhost ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
external-svc ExternalName <none> www.baidu.com <none> 20h
kubernetes ClusterIP 192.168.111.1 <none> 443/TCP 6d21h
nginx-svc ClusterIP 192.168.111.75 <none> 80/TCP 21h
[root@localhost ~]# curl 127.0.0.1:10249/proxyMode
iptables
[root@localhost ~]# ss -anpt | grep 10249
LISTEN 0 4096 127.0.0.1:10249 0.0.0.0:* users:(("kube-proxy",pid=1839,fd=12))
注:kube-proxy调用iptables实现请求重定向
(3)iptables 规则分析
# 查看所有规则
[root@localhost ~]# iptables -t nat -S
# 查看针对 service 流量入口专门创建了 KUBE-SERVICES 链
[root@localhost ~]# iptables -S -t nat | grep nginx-svc
-A KUBE-SEP-6QXBMRE2QCRINYBB -s 172.17.171.77/32 -m comment --comment "default/nginx-svc" -j KUBE-MARK-MASQ
-A KUBE-SEP-6QXBMRE2QCRINYBB -p tcp -m comment --comment "default/nginx-svc" -m tcp -j DNAT --to-destination 172.17.171.77:80
-A KUBE-SEP-FDRNTKCY4SE44FCM -s 172.17.189.73/32 -m comment --comment "default/nginx-svc" -j KUBE-MARK-MASQ
-A KUBE-SEP-FDRNTKCY4SE44FCM -p tcp -m comment --comment "default/nginx-svc" -m tcp -j DNAT --to-destination 172.17.189.73:80
-A KUBE-SERVICES -d 192.168.111.75/32 -p tcp -m comment --comment "default/nginx-svc cluster IP" -m tcp --dport 80 -j KUBE-SVC-HL5LMXD5JFHQZ6LN
-A KUBE-SVC-HL5LMXD5JFHQZ6LN ! -s 172.17.0.0/16 -d 192.168.111.75/32 -p tcp -m comment --comment "default/nginx-svc cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SVC-HL5LMXD5JFHQZ6LN -m comment --comment "default/nginx-svc -> 172.17.171.77:80" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-6QXBMRE2QCRINYBB
-A KUBE-SVC-HL5LMXD5JFHQZ6LN -m comment --comment "default/nginx-svc -> 172.17.189.73:80" -j KUBE-SEP-FDRNTKCY4SE44FCM
如果 访问地址 192.168.111.75/32,目标端口是 80,则会进入 KUBE-SVC-HL5LMXD5JFHQZ6LN链,即上边展示规则之一:
-A KUBE-SERVICES -d 192.168.111.75/32 -p tcp -m comment --comment "default/nginx-svc cluster IP" -m tcp --dport 80 -j KUBE-SVC-HL5LMXD5JFHQZ6LN
紧接着继续往下匹配,这里利用了 iptables 的 random 模块,因此,kube-proxy 的 iptables 模式采用随机数实现了服务的负载均衡:
-A KUBE-SVC-HL5LMXD5JFHQZ6LN ! -s 172.17.0.0/16 -d 192.168.111.75/32 -p tcp -m comment --comment "default/nginx-svc cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SVC-HL5LMXD5JFHQZ6LN -m comment --comment "default/nginx-svc -> 172.17.171.77:80" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-6QXBMRE2QCRINYBB
-A KUBE-SVC-HL5LMXD5JFHQZ6LN -m comment --comment "default/nginx-svc -> 172.17.189.73:80" -j KUBE-SEP-FDRNTKCY4SE44FCM
这里匹配到了两个链:KUBE-SEP-6QXBMRE2QCRINYBB和KUBE-SEP-FDRNTKCY4SE44FCM
KUBE-SEP-6QXBMRE2QCRINYBB 链的作用是 通过 DNAT 将请求发送到 172.17.171.77:80
KUBE-SEP-FDRNTKCY4SE44FCM 链的作用是 通过 DNAT 将请求发送到 172.17.189.73:80
即如下规则:
-A KUBE-SEP-6QXBMRE2QCRINYBB -p tcp -m comment --comment "default/nginx-svc" -m tcp -j DNAT --to-destination 172.17.171.77:80
-A KUBE-SEP-FDRNTKCY4SE44FCM -p tcp -m comment --comment "default/nginx-svc" -m tcp -j DNAT --to-destination 172.17.189.73:80
总结:iptables借助KUBE-SERVICES(cluster ip)> KUBE-SVC(轮询算法)> KUBE-SEP(DNAT策略)这条工作链实现了负载均衡调度
(4)nodeport 规则分析
分析完 ClusterIP 的 iptables 规则后,接下来看一下 NodePort 的访问方式:
[root@localhost ~]# kubectl edit svc nginx-svc
service/nginx-svc edited
[root@localhost ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
external-svc ExternalName <none> www.baidu.com <none> 20h
kubernetes ClusterIP 192.168.111.1 <none> 443/TCP 6d21h
nginx-svc NodePort 192.168.111.75 <none> 80:30753/TCP 21h
[root@localhost ~]# iptables -S -t nat | grep nginx-svc
-A KUBE-EXT-HL5LMXD5JFHQZ6LN -m comment --comment "masquerade traffic for default/nginx-svc external destinations" -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/nginx-svc" -m tcp --dport 30753 -j KUBE-EXT-HL5LMXD5JFHQZ6LN
-A KUBE-SEP-6QXBMRE2QCRINYBB -s 172.17.171.77/32 -m comment --comment "default/nginx-svc" -j KUBE-MARK-MASQ
-A KUBE-SEP-6QXBMRE2QCRINYBB -p tcp -m comment --comment "default/nginx-svc" -m tcp -j DNAT --to-destination 172.17.171.77:80
-A KUBE-SEP-FDRNTKCY4SE44FCM -s 172.17.189.73/32 -m comment --comment "default/nginx-svc" -j KUBE-MARK-MASQ
-A KUBE-SEP-FDRNTKCY4SE44FCM -p tcp -m comment --comment "default/nginx-svc" -m tcp -j DNAT --to-destination 172.17.189.73:80
-A KUBE-SERVICES -d 192.168.111.75/32 -p tcp -m comment --comment "default/nginx-svc cluster IP" -m tcp --dport 80 -j KUBE-SVC-HL5LMXD5JFHQZ6LN
-A KUBE-SVC-HL5LMXD5JFHQZ6LN ! -s 172.17.0.0/16 -d 192.168.111.75/32 -p tcp -m comment --comment "default/nginx-svc cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SVC-HL5LMXD5JFHQZ6LN -m comment --comment "default/nginx-svc -> 172.17.171.77:80" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-6QXBMRE2QCRINYBB
-A KUBE-SVC-HL5LMXD5JFHQZ6LN -m comment --comment "default/nginx-svc -> 172.17.189.73:80" -j KUBE-SEP-FDRNTKCY4SE44FCM
NodePort 的访问入口链是 KUBE-NODEPORTS,通过节点的 30753端口访问 NodePort,则会进入 KUBE-EXT-HL5LMXD5JFHQZ6LN链,如下:
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/nginx-svc" -m tcp --dport 30753 -j KUBE-EXT-HL5LMXD5JFHQZ6LN
接下来的跳转跟 ClusterIP 方式类似:
-A KUBE-SVC-HL5LMXD5JFHQZ6LN ! -s 172.17.0.0/16 -d 192.168.111.75/32 -p tcp -m comment --comment "default/nginx-svc cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SVC-HL5LMXD5JFHQZ6LN -m comment --comment "default/nginx-svc -> 172.17.171.77:80" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-6QXBMRE2QCRINYBB
-A KUBE-SVC-HL5LMXD5JFHQZ6LN -m comment --comment "default/nginx-svc -> 172.17.189.73:80" -j KUBE-SEP-FDRNTKCY4SE44FCM
工作链:KUBE-NODEPORTS > KUBE-SVC > KUBE-SEP(因为包含cluster ip 规则,所以还是能够看到KUBE-SERVICES的)
综上所述, iptables 模式最主要的链是 KUBE-SERVICES 、 KUBE-SVC-*和 KUBE-SEP-*:
- KUBE-SERVICES 链是访问集群内服务的数据包入口点,它会根据匹配到的目标 IP :port 将数据包分发到相应的 KUBE-SVC-*链
- KUBE-SVC-*链相当于一个负载均衡器,它会将数据包平均分发到 KUBE-SEP-* 链 。 每个 KUBE-SVC-* 链后面的 KUBE-SEP-*链都和 Service 的后端 Pod 数量一样
- KUBE-SEP-*链通过 DNAT 将连接的目的地址和端口从 Service 的 IP:port 替换为后端Pod 的 IP : port ,从而将流量转发到相应的 Pod
(5)iptabales vs IPVS
iptables的不足:iptables 和 IPVS 在刷新服务路由规则上的时延对比

- IPVS 代理模式使用哈希表作为基础数据结构,并且在内核空间中工作
- 所以与 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向通信的延迟要短,并且在同步代理规则时具有更好的性能
- 与其他代理模式相比,IPVS 模式还支持更高的网络流量吞吐量
(6)切换 kube-proxy 工作模式
[root@localhost ~]# kubectl -n kube-system edit cm kube-proxy
mode: "ipvs"
configmap/kube-proxy edited
[root@localhost ~]# kubectl -n kube-system get pod
NAME READY STATUS RESTARTS AGE
kube-proxy-7tlv7 1/1 Running 1 (135m ago) 23h
kube-proxy-jbbxd 1/1 Running 1 (135m ago) 23h
kube-proxy-q6fg8 1/1 Running 7 (9h ago) 6d22h
# 删除之后会重新读取
[root@localhost ~]# kubectl delete -n kube-system pod kube-proxy-7tlv7 kube-proxy-jbbxd kube-proxy-q6fg8
pod "kube-proxy-7tlv7" deleted
pod "kube-proxy-jbbxd" deleted
pod "kube-proxy-q6fg8" deleted
[root@localhost ~]# curl 127.0.0.1:10249/proxyMode
ipvs
(7)再次查看规则
[root@localhost ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.17.219.64:30753 rr
-> 172.17.171.77:80 Masq 1 0 0
-> 172.17.189.73:80 Masq 1 0 0
TCP 192.168.5.110:30753 rr
-> 172.17.171.77:80 Masq 1 0 0
-> 172.17.189.73:80 Masq 1 0 0
TCP 192.168.111.1:443 rr
-> 192.168.5.110:6443 Masq 1 1 0
TCP 192.168.111.10:53 rr
-> 172.17.219.120:53 Masq 1 0 0
-> 172.17.219.121:53 Masq 1 0 0
TCP 192.168.111.10:9153 rr
-> 172.17.219.120:9153 Masq 1 0 0
-> 172.17.219.121:9153 Masq 1 0 0
TCP 192.168.111.75:80 rr
-> 172.17.171.77:80 Masq 1 0 0
-> 172.17.189.73:80 Masq 1 0 0
UDP 192.168.111.10:53 rr
-> 172.17.219.120:53 Masq 1 0 0
-> 172.17.219.121:53 Masq 1 0 0
三、网络代理对象-Ingress

1.简介
[root@localhost ~]# kubectl api-resources | grep ingress
ingressclasses networking.k8s.io/v1 false IngressClass
ingresses ing networking.k8s.io/v1 true Ingress
# true:对象属于命名空间级别(只能在命名空间中使用)
# false:对象属于集群级别(集群中的任意一个命名空间都能够找到)
- Ingress :作为流量的总入口,统管集群的进出口数据,主要用于管理集群外部访问服务的方式
- Ingress Controller :读取、应用 Ingress 规则,处理、调度流量(类似于service的kube-proxy)
- IngressClass:插在 Ingress 和 IngressController 中间,协调流量规则和控制器,解除了 Ingress 和 Ingress Controller 的强绑定关系

注:Ingress Controller 主要由社区来实现,比如 Nginx, 就有 Nginx Ingress Controller
2.Ingress 的作用
- 路由流量:Ingress 能够基于请求的路径或主机名将流量路由到不同的服务上。例如,用户可以访问 example.com/api 时,将请求路由到服务A,而访问 example.com/ui 时,则将请求路由到服务B
- 反向代理功能:Ingress 作为反向代理,将外部的请求转发到集群内部的合适服务上。通过在 Ingress 中定义规则,Kubernetes 能够控制如何处理外部请求,并将其正确地转发到集群内部的服务
- SSL/TLS 加密:Ingress 允许用户配置 SSL/TLS 证书来加密通信。这样,Ingress 控制器能够在外部请求和 Kubernetes 集群之间实现 HTTPS 加密通信
- 负载均衡:Ingress 控制器通常与负载均衡结合使用,可以实现跨多个服务实例的流量分发,从而提高可用性和系统的扩展性
- 访问控制:Ingress 还可以与身份验证和授权机制结合,限制哪些用户或系统可以访问特定的服务。这通常是通过 HTTP 基本认证、OAuth 或其他验证机制来实现的
3.部署Ingress NGINX Controller

# 相关资源可以去我上传的资源仓库中下载
[root@localhost ingress-nginx-controller]# pwd
/root/10-ingress/ingress-nginx-controller
[root@localhost ingress-nginx-controller]# kubectl apply -f deploy.yaml
[root@localhost ingress-nginx-controller]# kubectl get -n ingress-nginx pod
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-4r4xq 0/1 Completed 0 14m
ingress-nginx-admission-patch-lkd4l 0/1 Completed 0 14m
ingress-nginx-controller-7f7cbcb485-hfjs5 1/1 Running 0 14m
# ingressclasses使用和创建时不用限制命名空间
[root@localhost ingress-nginx-controller]# kubectl get ingressclasses.networking.k8s.io
NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx <none> 18m
4. Ingress YAML对象
[root@localhost 10-ingress]# kubectl create ingress nginx-ing --rule="nginx.example.com/=nginx-svc:80" --class=nginx --dry-run=client -o yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
creationTimestamp: null
name: nginx-ing
spec:
ingressClassName: nginx
rules: # 七层转发规则
- host: nginx.example.com # 域名 http://nginx.example.com/
http:
paths:
- backend:
service:
name: nginx-svc # 四层 svc
port:
number: 80
path: /
pathType: Exact # 精确匹配(Prefix:前缀匹配)
status:
loadBalancer: {}
5.创建Ingress
[root@localhost 10-ingress]# cat nginx-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ing
spec:
ingressClassName: nginx
rules:
- host: nginx.example.com
http:
paths:
- path: /
pathType: Exact
backend:
service:
name: nginx-svc
port:
number: 80
[root@localhost 10-ingress]# kubectl apply -f nginx-ingress.yaml
ingress.networking.k8s.io/nginx-ing unchanged
[root@localhost 10-ingress]# kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-ing nginx nginx.example.com 80 74s

从浏览器访问 nginx.example.com:80,nginx.example.com 解析到 IP node节点的 IP
# 通过 NodePort 功能来访问 LoadBalancer 类型的 Service,30080 就是这个 NodePort
[root@localhost 10-ingress]# kubectl -n ingress-nginx get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 192.168.111.126 <pending> 80:30080/TCP,443:30443/TCP 49m
ingress-nginx-controller-admission ClusterIP 192.168.111.112 <none> 443/TCP 49m
[root@localhost 10-ingress]# kubectl -n ingress-nginx get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-admission-create-4r4xq 0/1 Completed 0 50m 172.17.171.78 worker <none> <none>
ingress-nginx-admission-patch-lkd4l 0/1 Completed 0 50m 172.17.171.79 worker <none> <none>
ingress-nginx-controller-7f7cbcb485-hfjs5 1/1 Running 0 50m 172.17.171.80 worker <none> <none>
# worker node 的ip地址是192.168.5.120,在本机hosts文件中配置
# 浏览时查看日志
[root@localhost 10-ingress]# kubectl -n ingress-nginx logs -f ingress-nginx-controller-7f7cbcb485-hfjs5
192.168.5.1 - - [21/Nov/2025:12:37:14 +0000] "GET / HTTP/1.1" 200 118 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" 433 0.002 [default-nginx-svc-80] [] 172.17.189.73:80 118 0.003 200 fd48bb4f331595cc9fa8549ff753d875
192.168.5.1 - - [21/Nov/2025:12:37:15 +0000] "GET / HTTP/1.1" 200 118 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" 459 0.001 [default-nginx-svc-80] [] 172.17.171.77:80 118 0.001 200 0dc7093776b81ce66f70ab66c6f3ad17

访问链路:http://nginx.example.com:30080/ > ingress-nginx-controller 实现 > 4 层 SVC nginx-svc > endpoint nginx-svc rr >pod
查看ingress-nginx-controller-pod的内部配置:

注:YAML的相关配置都已经被写入nginx.conf文件当中
补充知识点:
[root@localhost 10-ingress]# vi ingress-nginx-controller/deploy.yaml
externalTrafficPolicy: Local
- externalTrafficPolicy: Cluster (集群中任意一个节点 IP + port,都可以访问)
- externalTrafficPolicy: Local (应用的 Pod 所有的节点 才可以), 保留 客户端请求源ip
6.路由流量转发
(1)大概图示

(2)启动coffee和tea配置
[root@localhost https-ingress]# cat cafe-dep.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee
spec:
replicas: 2
selector:
matchLabels:
app: coffee
template:
metadata:
labels:
app: coffee
spec:
containers:
- name: coffee
image: registry.cn-beijing.aliyuncs.com/xxhf/nginx-hello:plain-text
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: coffee-svc
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: coffee
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tea
spec:
replicas: 3
selector:
matchLabels:
app: tea
template:
metadata:
labels:
app: tea
spec:
containers:
- name: tea
image: registry.cn-beijing.aliyuncs.com/xxhf/nginx-hello:plain-text
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: tea-svc
labels:
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: tea
# 启动配置
[root@localhost https-ingress]# kubectl apply -f cafe-dep.yaml
deployment.apps/coffee created
service/coffee-svc created
deployment.apps/tea created
service/tea-svc created
# 查看pod
[root@localhost https-ingress]# kubectl get pod
NAME READY STATUS RESTARTS AGE
coffee-8648d678f9-55dwf 1/1 Running 0 23s
coffee-8648d678f9-bdxwl 1/1 Running 0 23s
tea-6d679c96d5-5cb4l 1/1 Running 0 23s
tea-6d679c96d5-fj68p 1/1 Running 0 23s
tea-6d679c96d5-rlvt5 1/1 Running 0 23s
# 查看svc
[root@localhost https-ingress]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
coffee-svc ClusterIP 192.168.111.18 <none> 80/TCP 29s
tea-svc ClusterIP 192.168.111.40 <none> 80/TCP 29s
(3)测试集群内互通
[root@localhost https-ingress]# curl 192.168.111.40
Server address: 172.17.219.123:8080
Server name: tea-6d679c96d5-5cb4l
Date: 21/Nov/2025:13:12:19 +0000
URI: /
Request ID: 384ef24fee37b44fc43a556591affbc6
[root@localhost https-ingress]# curl 192.168.111.18
Server address: 172.17.189.75:8080
Server name: coffee-8648d678f9-55dwf
Date: 21/Nov/2025:13:12:26 +0000
URI: /
Request ID: ffce9d39f96ef88a2cbd187bf23fc9d0
(4)创建七层Ingress
[root@localhost https-ingress]# cat cafe-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cafe-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
ingressClassName: nginx # class name
rules: # 规则 反向代理
- host: cafe.xxhf.cc
http:
paths:
- path: /tea
pathType: Prefix
backend:
service:
name: tea-svc
port:
number: 80
- path: /coffee
pathType: Prefix
backend:
service:
name: coffee-svc
port:
number: 80
[root@localhost https-ingress]# kubectl apply -f cafe-ingress.yaml
ingress.networking.k8s.io/cafe-ingress created
[root@localhost https-ingress]# kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
cafe-ingress nginx cafe.xxhf.cc 80 24s
在主机的hosts文件中配置:192.168.5.120 cafe.xxhf.cc,之后访问浏览器:

查看浏览日志:
[root@localhost https-ingress]# kubectl -n ingress-nginx get pod
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-4r4xq 0/1 Completed 0 151m
ingress-nginx-admission-patch-lkd4l 0/1 Completed 0 151m
ingress-nginx-controller-7f7cbcb485-hfjs5 1/1 Running 0 151m
[root@localhost https-ingress]# kubectl -n ingress-nginx logs -f ingress-nginx-controller-7f7cbcb485-hfjs5
192.168.5.1 - - [21/Nov/2025:13:33:41 +0000] "GET /coffee HTTP/1.1" 200 163 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" 460 0.001 [default-coffee-svc-80] [] 172.17.171.82:8080 163 0.002 200 b238b46f8d0977f5968fb75a6b5c56d2
192.168.5.1 - - [21/Nov/2025:13:33:41 +0000] "GET /coffee HTTP/1.1" 200 163 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" 460 0.004 [default-coffee-svc-80] [] 172.17.189.75:8080 163 0.003 200 a3ce13c89ed22038d6c051c3c4e25f4b
7.SSL/TLS 加密
(1)创建 TLS 类型 Secret
[root@localhost cafe.xxhf.cc_nginx]# pwd
/root/10-ingress/https-ingress/cafe.xxhf.cc_nginx
[root@localhost cafe.xxhf.cc_nginx]# ll
总用量 24
-rw-rw-rw- 1 root root 4466 10月 23 08:30 cafe.xxhf.cc_bundle.crt # 证书
-rw-rw-rw- 1 root root 4466 10月 23 08:30 cafe.xxhf.cc_bundle.pem
-rw-rw-rw- 1 root root 1122 10月 23 08:30 cafe.xxhf.cc.csr
-rw-rw-rw- 1 root root 1704 10月 23 08:30 cafe.xxhf.cc.key # 私钥
[root@localhost cafe.xxhf.cc_nginx]# kubectl create secret tls cafe-secret \
--cert=cafe.xxhf.cc_bundle.crt \
--key=cafe.xxhf.cc.key
secret/cafe-secret created
[root@localhost cafe.xxhf.cc_nginx]# kubectl get secrets
NAME TYPE DATA AGE
cafe-secret kubernetes.io/tls 2 116s
# 查看证书
[root@localhost cafe.xxhf.cc_nginx]# kubectl get secrets cafe-secret -o yaml
(2)给 ingress 添加 TLS 属性
[root@localhost https-ingress]# cat cafe-ingress-tls.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cafe-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/enable-access-log: "false"
spec:
ingressClassName: nginx
tls:
- hosts:
- cafe.xxhf.cc
secretName: cafe-secret
rules:
- host: cafe.xxhf.cc
http:
paths:
- path: /tea
pathType: Prefix
backend:
service:
name: tea-svc
port:
number: 80
- path: /coffee
pathType: Prefix
backend:
service:
name: coffee-svc
port:
number: 80
[root@localhost https-ingress]# kubectl apply -f cafe-ingress-tls.yaml
ingress.networking.k8s.io/cafe-ingress configured
[root@localhost https-ingress]# kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
cafe-ingress nginx cafe.xxhf.cc 80, 443 34m
nginx-ing nginx nginx.example.com 80 125m
(3)浏览器访问


8.访问控制
(1)创建 htpasswd 文件
[root@localhost auth-ingress]# htpasswd -c auth xxhf
New password:
Re-type new password:
Adding password for user xxhf
[root@localhost auth-ingress]# ll
总用量 8
-rw-r--r-- 1 root root 43 11月 21 21:55 auth
-rw-r--r-- 1 root root 712 9月 23 10:06 auth-ingress.yaml
[root@localhost auth-ingress]# cat auth
xxhf:$apr1$p/OldVUp$OpyTWnCmH/pAMh.c21l1T1
(2)创建 secret 文件
[root@localhost auth-ingress]# kubectl create secret generic basic-auth --from-file=auth
secret/basic-auth created
(3)创建 ingress
[root@localhost auth-ingress]# cat auth-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-with-auth
annotations:
# type of authentication
nginx.ingress.kubernetes.io/auth-type: basic
# name of the secret that contains the user/password definitions
nginx.ingress.kubernetes.io/auth-secret: basic-auth
# message to display with an appropriate context why the authentication is required
nginx.ingress.kubernetes.io/auth-realm: 'Please Input Your Username and Password'
spec:
ingressClassName: nginx
rules:
- host: auth.xxhf.cc
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
[root@localhost auth-ingress]# kubectl apply -f auth-ingress.yaml
ingress.networking.k8s.io/ingress-with-auth created
[root@localhost auth-ingress]# kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
cafe-ingress nginx cafe.xxhf.cc 80, 443 45m
ingress-with-auth nginx auth.xxhf.cc 80 16s
nginx-ing nginx nginx.example.com 80 135m
- nginx.ingress.kubernetes.io/auth-type:认证类型,可以是basic和digest
- nginx.ingress.kubernetes.io/auth-secret:密码文件的Secret名称
- nginx.ingress.kubernetes.io/auth-realm:需要密码认证的消息提醒
(4)浏览器访问
注:要先修改主机hosts文件:192.168.5.120 auth.xxhf.cc

(5)修改访问端口
-
LoadBalancer:集群外会有一个单独的ip,监听的就是80/443端口
-
修改 ingress controller 配置 80 443 与 宿主机 网络 不做隔离
因为修改属性后无法更新,只能删除重建
[root@localhost 10-ingress]# kubectl delete -f ingress-nginx-controller/deploy.yaml
[root@localhost 10-ingress]# vi ingress-nginx-controller/deploy.yaml

[root@localhost 10-ingress]# kubectl apply -f ingress-nginx-controller/deploy.yaml
[root@localhost 10-ingress]# kubectl get -n ingress-nginx pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-admission-create-gknkk 0/1 Completed 0 49s 172.17.171.88 worker <none> <none>
ingress-nginx-admission-patch-mlpxv 0/1 Completed 1 49s 172.17.171.87 worker <none> <none>
ingress-nginx-controller-548b89d74d-hhbph 1/1 Running 0 49s 192.168.5.120 worker <none> <none>
# 可以看到运行在worker节点上,我们来到worker节点5.120
[root@worker local]# netstat -nltp |grep 443
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 13352/nginx: master
tcp6 0 0 :::8443 :::* LISTEN 13241/nginx-ingress
tcp6 0 0 :::443 :::* LISTEN 13352/nginx: master

这样更符合我们的使用习惯