惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Help Net Security
Help Net Security
G
Google Developers Blog
雷峰网
雷峰网
WordPress大学
WordPress大学
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Engineering at Meta
Engineering at Meta
Security Latest
Security Latest
T
Threat Research - Cisco Blogs
AWS News Blog
AWS News Blog
F
Full Disclosure
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Exploit Database - CXSecurity.com
J
Java Code Geeks
U
Unit 42
C
Cyber Attacks, Cyber Crime and Cyber Security
V
V2EX
C
Cisco Blogs
博客园 - 司徒正美
Project Zero
Project Zero
L
LINUX DO - 热门话题
阮一峰的网络日志
阮一峰的网络日志
Blog — PlanetScale
Blog — PlanetScale
Scott Helme
Scott Helme
A
About on SuperTechFans
Hugging Face - Blog
Hugging Face - Blog
S
Securelist
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
S
Schneier on Security
G
GRAHAM CLULEY
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyberwarzone
Cyberwarzone
MongoDB | Blog
MongoDB | Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 叶小钗
T
Threatpost
Recorded Future
Recorded Future
C
CXSECURITY Database RSS Feed - CXSecurity.com
宝玉的分享
宝玉的分享
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
The Register - Security
The Register - Security
S
Security Archives - TechRepublic
博客园 - Franky
N
News | PayPal Newsroom
Simon Willison's Weblog
Simon Willison's Weblog
S
SegmentFault 最新的问题
W
WeLiveSecurity
A
Arctic Wolf
B
Blog

云野开源志

OpenClaw npm 升级踩坑记:从版本冲突到模块丢失 免责声明 openclaw(moltbot、Clawdbot)常见异常 大模型配置-千问免费版 初始化OpenClaw 安装openclaw记录 大年初一桃花谷 CheckSSL.sh - SSL证书到期时间监控脚本 g.sh - Go语言环境管理工具安装脚本 install-cri-docker.sh - cri-dockerd安装脚本 install-docker.sh - Docker Engine快速安装脚本 install-docker2.sh - Docker 交互式安装脚本 install-nginx.sh - Nginx官方源快速安装脚本 install-zerotier.sh - ZeroTier 虚拟网络快速安装脚本 mng.sh - Nginx配置文件合并脚本 OpenSSL.sh - 自签名 SSL 证书生成脚本 SystemInfoMonitor.sh - 系统资源监控告警脚本 UpdateImages.sh - Docker 镜像批量更新脚本 为Hugo Next主题添加Umami统计支持 解忧杂货铺 - 栏目声明 Certd - 解决多平台SSL证书管理难题的神器 轻量级网络端口监控工具 GeoLite2 自动搬运仓库使用手册 MaxMind 免费账号注册 CloudFlare Accel Docker 搭建私有 DNS 服务器 hugo-theme-stack集成Umami openresty编译添加geoip2模块支持 GPU加速云原生应用,开启高性能计算新纪元 4. K8S 控制器 Rancher搭建 3. K8S Pod 资源管理 2. K8S 基础资源管理 1. K8S 简介和认证介绍 Rancher集成AzureAD认证 Harbor 部署搭建 站点留言板 关于 友情链接
5. K8S Service与Ingress
云野开源志 · 2023-07-25 · via 云野开源志

总结摘要

本文深入讲解 Kubernetes 中 Service 与 Ingress 的核心机制。内容涵盖 Service 的作用(服务发现与负载均衡)、工作原理(通过 Endpoint 关联 Pod)、四种类型(ClusterIP/NodePort/LoadBalancer/ExternalName)的详细配置与适用场景,并特别说明了在云平台(如 Azure AKS)使用 LoadBalancer 时的权限与静态 IP 配置要点。同时为后续引入 Ingress 做铺垫,阐明其作为七层入口网关与四层 Service 的互补关系,是理解 K8S 网络模型的关键篇章。

Kubernetes Service与Ingress

srevice概念

kubernetes Pod是短暂的,它们会被创建,也会死掉,并且是不可被复活的。

ReplicationControllers动态的创建和销毁Pods(比如规模扩大或者缩小,或者执行动态更新)。每个Pod都有自己的IP,这些IP随着时间的变换,也不能持续依赖,这样就引发一个问题:如果一些Pods(后台、后端)提供了一些功能共其他Pod使用(前台),再Kubernetes集群中是如何让这些前台能够持续的追踪到这些后台的。

答案是:==service==

Kubernetes Service是一个定义了一组Pod的策略的抽象,我们也有时候叫做宏观服务。这些服务标记的Pod(一般)都是听过label Selector决定的。(下面会讲到为什么需要一个没有 label selector 的服务)

假设后台是一个图形处理器的后台,并且有3个副本。这些副本是可以相互代替的,并且,前台需要关心使用的哪一台Pod,当这个承载前台请求的Pod发生变化时,前台并不需要知道这些变换,或者追踪后台的这些副。service定义的抽象能够解耦这种关联。

对于Kubernetes 原生的应用,Kubernetes提供了一个简单的Endpoints API,这个Endpoints api 的作用就相当于一个服务中的Pod发生变化时,Endpoints API随之变化,对于那些不是原生的程序,Kubernetes提供了一个基于虚拟IP的网桥的服务,这个服务会将请求转发到对应的后台Pod。

Service对象的IP地址也成为ClusterIP,它位于为Kubernetes集群配置指定专用的IP地址范围之内,是一种虚拟的IP地址,它再Service对象创建之后保持不变,并且能够被同一集群中的Pod资源所访问。Service端口用于接收客户端请求,并将请求转发至后端的Pod应用端口,这样的代理机制,也称为端口代理,它基于TCP/IP协议栈的传输层。

Service存在的意义:

​ 1、防止Pod失联(服务发现)

​ 2、定义一组Pod的访问策略(负载均衡)

Pod与service的关系:

​ 1、通过label-selector相关联

​ 2、通过service实现Pod的负载均衡(TCP、UDP四层)

使用kubectl explain svc查看更多关键字

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    protocol: TCP
    port: 80
    targetPort: 9376

service不会直接到pod,service是直接到endpoint资源,就是地址加端口,再由endpoint再关联到pod。

service只要创建完,就会再dns中添加一个资源记录进行解析,添加完成即可进行解析。资源记录的格式为:

1
SVC_NAME.NS_NAME.DOMAIN.LTD.

默认的集群service的A记录:

my-service服务创建的A记录:

1
my-service.default.svc.cluster.local.

Service类型

Kubernetes ServiceTypes 允许指定一个需要的类型的Service,默认是Cluster IP类型。

也可以使用Ingress来暴露自己的服务。Ingress不是一种服务类型,但它充当集群的入口点。它可以将路由规则整合到一个资源中,因为它可以在同一IP地址下公开多个服务。

Type的类型如下:

ClusterIP:

通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是默认的 ServiceType

NodePort

通过每个节点上的 IP 和静态端口(NodePort)暴露服务。 NodePort 服务会路由到自动创建的 ClusterIP 服务。 通过请求 <节点 IP>:<节点端口>,你可以从集群的外部访问一个 NodePort 服务。

如果将type字段设置为NodePort,则Kubernetes控制平面将在--service-node-port-range标志指定的范围内分配端口(默认值:30000-32767)。每个节点将那个端口(每个节点上的相同端口号)代理到你的服务器中。你的服务在其.spec.port[*].nodePort字段中要求分配的端口。

如果你想指定特定的IP代理端口,则可以设置kube-proxy中的--nodeport-addresses参数或者将kube-porxy配置文件 中的等效nodePodrtAddresses字段设置为特定的IP快。该标志采用逗号分隔的IP块列表(例如:10.0.0.0/8192.0.2.0/25)来指定kube-proxy应该认为是此节点本地的IP地址范围。

例如,如果你使用 --nodeport-addresses=127.0.0.0/8 标志启动 kube-proxy, 则 kube-proxy 仅选择 NodePort Services 的本地回路接口。 --nodeport-addresses 的默认值是一个空列表。 这意味着 kube-proxy 应该考虑 NodePort 的所有可用网络接口。 (这也与早期的 Kubernetes 版本兼容)。

如果需要特定的端口号,你可以在 nodePort 字段中指定一个值。 控制平面将为你分配该端口或报告 API 事务失败。 这意味着你需要自己注意可能发生的端口冲突。 你还必须使用有效的端口号,该端口号在配置用于 NodePort 的范围内。

使用 NodePort 可以让你自由设置自己的负载均衡解决方案, 配置 Kubernetes 不完全支持的环境, 甚至直接暴露一个或多个节点的 IP。

需要注意的是,Service 能够通过 <NodeIP>:spec.ports[*].nodePortspec.clusterIp:spec.ports[*].port 而对外可见。 如果设置了 kube-proxy 的 --nodeport-addresses 参数或 kube-proxy 配置文件中的等效字段, <NodeIP> 将被过滤 NodeIP。

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app: MyApp
  ports:
      # 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
    - port: 80
      targetPort: 80
      # 可选字段
      # 默认情况下,为了方便起见,Kubernetes 控制平面会从某个范围内分配一个端口号(默认:30000-32767)
      nodePort: 30007

loadBalancer:

使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上。

在使用支持外部负载均衡器的云提供商的服务时,设置 type 的值为 "LoadBalancer", 将为 Service 提供负载均衡器。 负载均衡器是异步创建的,关于被提供的负载均衡器的信息将会通过 Service 的 status.loadBalancer 字段发布出去。

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  clusterIP: 10.0.171.239
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
      - ip: 192.0.2.127

来自外部负载均衡器的流量将直接重定向到后端 Pod 上,不过实际它们是如何工作的,这要依赖于云提供商。

某些云提供商允许设置 loadBalancerIP。 在这些情况下,将根据用户设置的 loadBalancerIP 来创建负载均衡器。 如果没有设置 loadBalancerIP 字段,将会给负载均衡器指派一个临时 IP。 如果设置了 loadBalancerIP,但云提供商并不支持这种特性,那么设置的 loadBalancerIP 值将会被忽略掉。

注意:

在 Azure 上,如果要使用用户指定的公共类型 loadBalancerIP,则 首先需要创建静态类型的公共 IP 地址资源。 此公共 IP 地址资源应与集群中其他自动创建的资源位于同一资源组中。 例如,MC_myResourceGroup_myAKSCluster_eastus

将分配的 IP 地址设置为 loadBalancerIP。确保你已更新云提供程序配置文件中的 securityGroupName。 有关对 CreatingLoadBalancerFailed 权限问题进行故障排除的信息, 请参阅 与 Azure Kubernetes 服务(AKS)负载平衡器一起使用静态 IP 地址 在 AKS 集群上使用高级联网时出现 CreatingLoadBalancerFailed

详细内容: 服务 | Kubernetes

ExternalName:

通过返回 CNAME 和对应值,可以将服务映射到 externalName 字段的内容(例如,foo.bar.example.com)。 无需创建任何类型代理。

类型为 ExternalName 的服务将服务映射到 DNS 名称,而不是典型的选择器,例如 my-service 或者 cassandra。 你可以使用 spec.externalName 参数指定这些服务。

例如,以下 Service 定义将 prod 名称空间中的 my-service 服务映射到 my.database.example.com

1
2
3
4
5
6
7
8
apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

说明: ExternalName 服务接受 IPv4 地址字符串,但作为包含数字的 DNS 名称,而不是 IP 地址。 类似于 IPv4 地址的外部名称不能由 CoreDNS 或 ingress-nginx 解析,因为外部名称旨在指定规范的 DNS 名称。 要对 IP 地址进行硬编码,请考虑使用 headless Services

当查找主机 my-service.prod.svc.cluster.local 时,集群 DNS 服务返回 CNAME 记录, 其值为 my.database.example.com。 访问 my-service 的方式与其他服务的方式相同,但主要区别在于重定向发生在 DNS 级别,而不是通过代理或转发。 如果以后你决定将数据库移到集群中,则可以启动其 Pod,添加适当的选择器或端点以及更改服务的 type