Kubernetes学习记录(六):深入理解service和Ingress
1. service
- 防止pod失联(服务发现)
- 定义一组pod的访问规则(负载均衡)
服务发现
假设现在是一个deployment控制器,一般为了保证高可用都会至少部署三个副本,而且三个pod都有独立的ip地址
当一个pod挂掉之后,deployment会立刻拉取一个新的pod,但是新pod的ip地址明显是和挂掉的那个pod不一样
这时候service就发挥了作用,前端和后端pod不需要通过ip地址来直接通信,而是经由service来做一个统一的管理操作
负载均衡
当我有多个副本时,客户端发送的请求需要具体转发到哪个pod上,这就是负载均衡
1.1 Pod和Service的关系
- pod与service通过label-selector关联
- 通过service实现pod的负载均衡(TCP/UDP四层,只负责IP数据包转发)
Service看起来就像是为Pod提供了一个网络代理的功能
1.2 Service常用类型
- ClusterIP:默认设置,集群内部使用
- NodePort:对外暴露应用
- LoadBalancer:对外暴露应用,适用于公有云
比如在一个客户端-后端-数据库的业务架构中,客户端-后端、后端-数据库之间的通信就要选择ClusterIP,因为这些都不需要暴露
而用户和客户端之间就需要使用NodePort,即我们要把客户端的服务暴露出去
1.2.1 ClusterIP
分配一个稳定的IP地址,即VIP,只能在集群内部访问,同一个namesapce内的pod
最典型的ClusterIP就是k8s集群服务的service,我们可以通过下面的指令查看所有的svc
kubectl get svc
这个虚拟IP可以在任意一个节点、任意一个pod内访问
1.2.2 NodePort
提供一个端口,供外部访问,但其存在一个问题就是可以通过所有的<NodeIP+port>的形式来访问
对外暴露的端口号从30000起,默认是集群随机分配的
也可以通过spec.ports.nodePort字段来指定一个暴露端口,但注意可能会存在端口占用情况
这个暴露的端口在每个节点都会监听,不论这个节点有没有提供服务的pod
外界访问任意一个node都可以获取服务,通过 <NodeIP:NodePort> 的形式,然后统一由service来做负载均衡
比如在下面这个svc列表中,web是作为NodePort类型的,可以看到它在 PORT(S)这一项是有两个端口号
左侧是集群内部访问的,也就是一种ClusterIP
右边是通过节点IP地址暴露出去的一个端口号
一般来讲,生产环境中所有的node都部署在内网,即使暴露了端口,在公网上也无法访问
这时候一般会有以下解决方案:
- 找一台有公网IP的服务器,使用nginx反向代理到node
- 使用外部负载均衡器,比如nginx、LVS、HAProxy做负载均衡,将流量转发到node
1.2.3 LoadBalancer
与NodePort类似,在每个节点上启用一个端口来暴露服务
除此之外,k8s还会请求底层云平台上的负载均衡器,将每个Node <NodeIP:NodePort> 作为后端添加进去
用户通过访问公有云上的负载均衡器来访问node
1.3 Service代理模式
1.3.1 Iptables
iptables是Service的默认模式
iptables能做什么?
- 阻断IP通信
- 端口映射NAT
- 跟踪包的状态
- 数据包的修改
kube-proxy组件默认实现iptables,具体来讲就是实现数据包在node之间的转发
将service相关规则来落地实现
如果使用NodePort的访问规则的话,我们在外部访问任意节点IP+暴露端口,采取轮询机制找到一个提供服务的pod
NodePort:192.167.11.89:30008
-> KUBE-SVC-XXXXXX (负载均衡) --probalility 0.3333333
-> KUBE-SEP-YYYYYYY
-> -j DNAT --to-destination 10.244.2.2:80 (提供服务的Pod)
iptables的特点:
- 灵活,功能强大
- 规则遍历匹配和更新,呈线性时延
1.3.2 IPVS
LVS就是基于ipvs模块实现的四层负载均衡器
ipvs特点:
- 工作在内核态,有更好的性能
- 调度算法丰富:rr、wrr、lc、wlc、ip hash ...
2. Ingress
为什么需要Ingress?
首先来看一下NodePort存在的问题:
- 一个端口只能一个服务来使用,因为在所有的Node上都暴露了这个端口
- 只支持四层的负载均衡
2.1 Ingress和Pod的关系
- 通过Service完成关联
- 通过Ingress Controller实现Pod的负载均衡,支持TCP/UDP四层和HTTP七层
2.2 部署Ingress Controller
Ingress Controller有很多实现,官方维护的是nginx控制器,其他的主流控制器也有Traefik和Istio
官方提供了很多第三方控制器的项目地址:Ingress 控制器 | Kubernetes
我们使用官方的nginx控制器,下载好yaml之后需要修改镜像源为国内镜像源,修改hostNetwork: true
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.2/deploy/static/provider/cloud/deploy.yaml > ic.yaml
根据这个YAML文件创建两个pod,其实是和节点数有关,这是以DaemonSet方式部署的
2.3 设置Ingress规则
对于下面这个ingress规则,首先需要指定kind为ingress
最重要的就是service字段,指明暴露的服务名称和端口
同时通过域名绑定服务,如果测试的话需要修改本机hosts来访问
2.4 Ingress根据URL路由到多个服务
比如在下面的示例中,Ingress管理了两个service
用户可以通过域名的方式来访问这两个service,其中/foo和/bar就负责路由的转发
这个Ingress规则的YAML文件如下所示:
Ingress规则中有两个后端service,路由路径分别为/foo和/bar
当我们访问foo.bar.com/foo时,ingress就会帮我路由到service1,访问foo.bar.com/bar时,ingress会路由到service2
其中的pathType: Prefix是前缀匹配,也就是说只要是以 "/foo" 开头的URL都会被路由到service1
匹配规则可见:Ingress | Kubernetes
2.5 Ingress Controller高可用方案
其中集群模式更为常见,可以在公网节点上部署一个负载均衡器,比如nginx,把流量转发给Ingress Controller
参考:
Installation Guide - NGINX Ingress Controller (kubernetes.github.io)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理