K8s网络之Service

K8s网络:服务发现与负载均衡

Ingress(七层) -> Service (SVC)(四层) > EndPoint -> kube-proxy -> Lvs/iptables

Ingress负责七层HTTP/HTTPS路由,将不同域名或路径的请求转发至对应Service;Service通过标签选择器关联后端Pod,创建Endpoints记录真实IP;kube-proxy监听Service变化,通过iptables或IPVS规则实现流量转发,确保请求精准到达目标Pod。整个过程实现解耦与动态更新,支撑应用弹性伸缩与高可用。

K8s网络解决的主要问题?

服务发现:如何找到Pod,Pod如何找到其他的Pod;

  • Pod内部通信:localhost:port
  • 用户查找Pod:Pod的ip:port
  • Pod与Pod通信:跨节点,但是不用NAT地址转换

CNI插件实现Pod间通信

  • Flannel:使用VXLAN“隧道”技术,适合中小型集群;
  • Calico:适合大规模集群;BGP 边界网关协议(Border Gateway Protocol,BGP)是互联网上一个核心的去中心化自治路由协议。BGP不使用传统的内部网关协议(IGP)的指标。

服务发现

通过Service实现:

  • 通过“标签”选中Pod,提供固定的入口(类似“VIP”),然后通过负载均衡;
  • 给Pod提供DNS服务,Pod通过域名访问Service;

Service -> EndPoint(动态的IP列表) -> Pod

创建Service时,自动创建EndPoints;

  • 网络和负载均衡:kube-proxy -> 系统内核(Lvs/iptables)

Service三大功能:

  1. 服务发现:通过DNS域名(如web-service.default.svc.cluster.local)

ServiceName.NameSpace.svc.cluster.local 替代动态Pod IP

      2、负载均衡:把请求平均分给背后的多个Pod,避免单个Pod过载;

      3、端口映射:隐藏Pod内部端口(如外部访问80端口,转发到Pod的8080端口)。

Service的四大模式/四种类型:

  • ClusterIP(默认):只允许集群内部访问,外部不可见,用于集群内部Pod间通信,例如:后端调用,数据库连接等;

前提是先拥有一个标签是app: my-app的Pod在运行,因为Service的Selector需要匹配Pod的标签,如果没有这样的标签,需要现添加一个,以下举例说明:

# 给名为my-nginx-66bf7cffd7-2vgl7的Pod添加标签

kubectl label pod my-nginx-66bf7cffd7-2vgl7 app=my-app

vim my-service.yaml

---

apiVersion: v1

kind: Service

metadata:

  name: my-clusterip-service

spec:

  type: ClusterIP #可省略,默认就是 ClusterIP

  selector:

    app: my-app   #匹配 Pod 的标签

  ports:

    - protocol: TCP

      port: 80    #Service 的端口,集群内的其他 Pod 通过该端口访问服务。

      targetPort: 80 #Pod 的端口,Service 将流量转发到该端口。

---

apiVersion: v1

kind: Service

metadata:

  name: my-clusterip-service

spec:

  type: ClusterIP

  clusterIP: 10.96.0.100  #手动指定 ClusterIP

  selector:

    app: my-app

  ports:

    - protocol: TCP

      port: 80

      targetPort: 80

# 应用yaml文件

kubectl apply -f my-service.yaml

# 验证svc运行情况并获取 ClusterIP 地址:

kubectl get svc my-clusterip-service

会出现以下:

NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE

my-clusterip-service   ClusterIP   10.110.83.243   <none>        80/TCP    16s

# 然后通过ClusterIP访问

curl 10.110.83.243

vim my-service.yaml

---

apiVersion: v1

kind: Service

metadata:

  name: my-clusterip-service

spec:

  type: ClusterIP #可省略,默认就是 ClusterIP

  selector:

    app: my-app   #匹配 Pod 的标签

  ports:

    - protocol: TCP

      port: 80    #Service 的端口,集群内的其他 Pod 通过该端口访问服务。

      targetPort: 80 #Pod 的端口,Service 将流量转发到该端口。

---

apiVersion: v1

kind: Service

metadata:

  name: my-clusterip-service

spec:

  type: ClusterIP

  clusterIP: 10.96.0.100  #手动指定 ClusterIP

  selector:

    app: my-app

  ports:

    - protocol: TCP

      port: 80

      targetPort: 80

# 应用yaml文件

kubectl apply -f my-service.yaml

# 验证svc运行情况并获取 ClusterIP 地址:

kubectl get svc my-clusterip-service

会出现以下:

NAME                          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE

my-clusterip-service   ClusterIP   10.110.83.243            <none>         80/TCP     16s

# 然后通过ClusterIP访问

curl 10.110.83.243

  • NodePort:外部通过任意Node的IP进行访问,NodePort的默认范围是30000-32767,但可以手动指定。简单服务、对外测试;

和上面同理,需要有一个标签和你的选择器写的标签一致。

vim 07-nodeport.yaml

apiVersion: v1

kind: Service

metadata:

  name: my-nodeport-service

spec:

  type: NodePort  #指定服务类型为 NodePort

  selector:       #用于匹配目标 Pod 的标签

    app: my-web   #匹配 Pod 的标签

  ports:

    - protocol: TCP

      port: 80         #Service 的端口,客户端通过该端口访问服务

      targetPort: 80 #Pod 的端口,Service 将流量转发到该端口

      nodePort: 30000  #可选,指定节点端口(范围 30000-32767)

# 应用yaml文件

kubectl apply -f 07-nodeport.yaml

# 验证Service

kubectl get svc

# 访问服务:使用节点 IP 和 NodePort 访问服务。(三个节点都可以)

​​​​​​http://<Node-IP>:30000

  • LoadBalancer:使用云厂商的负载均衡器,实现对外的服务,适合在生产环境云平台上使用;

# 先给Pod添加标签

kubectl label pod my-nginx-66bf7cffd7-4k5hc aihao=haha

# 下载插件,应用 MetalLB 资源

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml

# 配置IP 地址池(示例为192.168.221.10-192.168.221.100

vim metallb-ip-pool.yaml

apiVersion: metallb.io/v1beta1

kind: IPAddressPool

metadata:

  name: example

  namespace: metallb-system

spec:

  addresses:

  - 192.168.221.10-192.168.221.100

---

apiVersion: metallb.io/v1beta1

kind: L2Advertisement

metadata:

  name: example

  namespace: metallb-system

kubectl apply -f metallb-ip-pool.yaml

cat 08-loadbalancer.yaml

apiVersion: v1

kind: Service

metadata:

  name: my-service

spec:

  type: LoadBalancer #指定服务类型为 LoadBalancer

  selector:    

    aihao: haha

  ports:

    - protocol: TCP

      port: 80    #服务暴露的端口(外部访问的端口)

      targetPort: 80  #Pod中应用监听的端口

# 应用yaml文件

kubectl apply -f 08-loadbalancer.yaml

# 检查服务状态,# EXTERNAL-IP #表示负载均衡器的外部 IP 地址,外部用户可以通过该地址访问服务。PORT(S) #显示服务端口和映射的节点端口。

kubectl get svc

NAME         TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE

my-service   LoadBalancer   10.109.77.71    192.168.221.10   80:32179/TCP   26s

# 一旦 EXTERNAL-IP 可用,外部用户可以通过以下方式访问服务:

http://<EXTERNAL-IP>:80或者用自己节点IP+端口号也能访问

# Pod内部也可以用域名来访问

curl my-nodeport-service.default.svc.cluster.local

  • ExternalName:域名转换,给域名起别名,Service通过DNS解析将请求转发到指定的外部域名。

# 配置一个yaml文件

vim 03-externalname.yaml

apiVersion: v1

kind: Service

metadata:

  name: svc1

spec:

  type: ExternalName

  externalName: httpbin.org   #这个可以看到502页面

  ports:

  - name: http

    port: 80

    protocol: TCP

targetPort: 80

# 应用yaml文件

kubectl apply -f 03-externalname.yaml

# 先查看有什么运行的Pod,然后随便进入一个Pod

kubectl exec -it my-web-664c6fd8c-t77gw -- bash

# 验证网站,可以看到网页内容

curl svcl.default.svc.cluster.local

特殊模式:

  • Headless(无IP):Service没有IP,也不做负载均衡,仅返回Pod列表;

vim 09-headless.yaml

---

apiVersion: apps/v1

kind: Deployment

metadata:

  creationTimestamp: null

  labels:

    app: yourapp

  name: yourapp

spec:

  replicas: 3

  selector:

    matchLabels:

      app: yourapp

  strategy: {}

  template:

    metadata:

      creationTimestamp: null

      labels:

        app: yourapp

    spec:

      containers:

      - image: 192.168.57.200:8099/library/nginx:1.24

        name: nginx

---

apiVersion: v1

kind: Service

metadata:

  name: web-service  # Headless Service名称,会在svc显示

  namespace: default

spec:

  clusterIP: None  # 关键:设置为None,声明为Headless Service

  selector:

    app: yourapp  # 关联标签为app=myapp的Pod

  ports:

  - name: http

    port: 80  # 服务端口

targetPort: 80  # Pod内应用监听的端口

kubectl apply -f 09-headless.yaml

<think>首先,用户的问题是关于KubernetesService的类型。用户明确说:“我想了解KubernetesService的类型 请问Kubernetes Service有哪些类型”。所以,我需要专注于回答这个。 从系统指令中,我有一些引用: - 引用[1]: 提到了Namespace、Pod、Deployment、Service的基本操作。 - 引用[2]: 直接说:“KubernetesService的种类。在Kubernetes v1.0版本Service是4层(TCP/UDP over IP)概念,在Kubernetes v1.1版本新增了Ingress API(beta版),用来表示7层(HTTP)服务”。这很重要。 - 引用[3]: “LoadBalancer是Kubernetes Service的一种类型”。 - 引用[4]: 详细描述了Service的类型,包括ClusterIP、NodePort、LoadBalancer等。 引用[4]特别有用,因为它列出了Service的类型:ClusterIP(默认)、NodePort、LoadBalancer等。 现在,回忆Kubernetes知识,Service的主要类型有: 1. ClusterIP:默认类型,为Service分配一个内部IP地址,只在集群内部可访问。 2. NodePort:在每个Node上暴露一个端口,允许外部访问。 3. LoadBalancer:在支持云提供商的集群中,创建一个外部负载均衡器来暴露Service。 4. ExternalName:通过返回CNAME记录,将Service映射到外部DNS名称。 此外,引用[2]提到Ingress API,但Ingress不是Service类型;它是独立的对象,用于管理HTTP路由。所以,我应该澄清这一点。 系统指令要求: - 使用中文回答。 - 回答结构清晰,帮助用户逐步解决问题。 - 行内数学表达式用$...$,独立公式用$$...$$,但这个问题可能不涉及数学公式。 - 生成相关问题。 - 在引用的段落末尾添加引用标识。 用户的问题是关于Service类型,所以我应该基于引用提供信息。 回答结构: 1. 介绍Service是什么:简要解释Kubernetes Service的作用,如服务发现、负载均衡。 2. 列出Service类型:详细描述每种类型。 3. 引用相关部分:在适当的地方添加引用标识。 4. 生成相关问题。 从引用: - [^2] 提到Service种类和Ingress。 - [^3] 提到LoadBalancer类型。 - [^4] 详细描述了Service类型:ClusterIP、NodePort、LoadBalancer。 所以,我可以整合这些。 最终回答应包括: - ClusterIP - NodePort - LoadBalancer - ExternalName 以及可能的其他如Headless Services,但引用中没有提到,所以我应该基于引用。 引用[4]说:“多种类型ClusterIP, NodePort, LoadBalancer 等”,所以包括“等”,可能包括ExternalName。 在Kubernetes官方文档中,标准类型是ClusterIP、NodePort、LoadBalancer、ExternalName。 生成相关问题:基于主题,如每种类型的用途、如何选择等。 回答结构: - 段落1:介绍Service。 - 段落2:描述类型,使用列表或清晰描述。 - 添加引用:在相关句子后添加[^n]。 - 最后,生成相关问题。</think>### Kubernetes Service 类型详解 在 Kubernetes 中,Service 是一个核心抽象资源,用于为一组 Pod 提供稳定的网络端点和访问策略。它解决了服务发现、负载均衡和解耦等问题,确保应用即使在后端 Pod 动态变化时也能被可靠访问。Service 的类型定义了如何暴露服务到不同网络范围(如集群内部或外部)。以下是 Kubernetes Service 的主要类型,基于官方文档和常见实践[^4]。 #### 1. ClusterIP(默认类型) - **描述**:ClusterIP 是 Service 的默认类型。它分配一个内部集群 IP 地址,该地址仅在 Kubernetes 集群内部可访问。外部客户端无法直接访问此服务。 - **用途**:适用于内部微服务通信,如数据库服务或后端 API,这些服务不需要外部暴露。 - **配置示例**: ```yaml apiVersion: v1 kind: Service metadata: name: my-service spec: type: ClusterIP # 可省略,因为默认 selector: app: MyApp ports: - protocol: TCP port: 80 # Service 端口 targetPort: 9376 # Pod 端口 ``` - **特点**:提供稳定虚拟 IP 和 DNS 名称(如 `my-service.default.svc.cluster.local`),支持负载均衡和会话保持(通过 `sessionAffinity` 配置)[^4]。 #### 2. NodePort - **描述**:NodePort 类型在每个集群节点上暴露一个静态端口(范围:30000-32767)。外部客户端可以通过任意节点的 IP 地址和该端口访问服务。流量会自动路由到后端 Pod。 - **用途**:适合开发测试环境或小型部署,允许外部访问集群内部服务,但不如 LoadBalancer 类型灵活。 - **配置示例**: ```yaml apiVersion: v1 kind: Service metadata: name: my-nodeport-service spec: type: NodePort selector: app: MyApp ports: - protocol: TCP port: 80 targetPort: 9376 nodePort: 31000 # 可选,不指定则自动分配 ``` - **特点**:在 ClusterIP 基础上添加节点端口映射,但需手动管理节点 IP,不适合大规模生产环境[^4]。 #### 3. LoadBalancer - **描述**:LoadBalancer 类型在支持云服务提供商(如 AWS、GCP 或 Azure)的集群中,自动创建一个外部负载均衡器。该负载均衡器分配一个外部可访问的 IP 地址,并将流量分发到多个 Pod。 - **用途**:理想用于生产环境,需要高可用性和外部访问的服务,如 Web 应用。 - **配置示例**: ```yaml apiVersion: v1 kind: Service metadata: name: my-lb-service spec: type: LoadBalancer selector: app: MyApp ports: - protocol: TCP port: 80 targetPort: 9376 ``` - **特点**:提供自动流量分发和健康检查,但依赖云提供商,可能产生额外成本。在本地集群中,可能需要额外插件(如 MetalLB)[^3][^4]。 #### 4. ExternalName - **描述**:ExternalName 类型将 Service 映射到一个外部 DNS 名称(如云数据库服务),而不是集群内部 Pod。它通过 CNAME 记录实现,不涉及负载均衡或代理。 - **用途**:用于集成外部服务,如第三方 API 或云存储,简化集群内访问。 - **配置示例**: ```yaml apiVersion: v1 kind: Service metadata: name: my-external-service spec: type: ExternalName externalName: my.database.example.com # 外部 DNS 名称 ``` - **特点**:无内部 IP,仅提供 DNS 重定向,适用于解耦场景[^4]。 #### 其他说明 - **Ingress 与 Service 的关系**:Ingress 不是 Service 类型,而是一个独立 API 对象(通常在 Kubernetes v1.1+ 可用),用于管理 HTTP/HTTPS 路由到后端 Service(通常是 ClusterIP 或 NodePort)。它提供 7 层(应用层)负载均衡,支持基于域名或路径的路由[^2]。 - **选择建议**:根据访问需求选择类型。例如: - 内部服务:ClusterIP。 - 简单外部访问:NodePort。 - 生产级外部暴露:LoadBalancer 或结合 Ingress。 - 集成外部资源:ExternalName。 Service 类型的设计体现了 Kubernetes 的灵活性,确保服务在不同环境中可靠运行[^1][^4]。 ### 相关问题 1. ClusterIP 和 NodePort 有什么区别?各自适用于什么场景? 2. 如何配置 LoadBalancer 类型在本地 Kubernetes 集群中使用? 3. ExternalName Service 如何实现服务发现?有什么限制? 4. Ingress 与 LoadBalancer Service 如何协作实现 HTTP 流量管理?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值