Kubernetes Service 核心概念与实操指南(分别使用yaml文件和命令行分别创建service版)

文章目录

  • [Kubernetes Service 核心概念与实操指南(使用yaml文件版)](#Kubernetes Service 核心概念与实操指南(使用yaml文件版))
    • 引言
    • [一、Service 核心作用](#一、Service 核心作用)
    • [二、kube-proxy 三种代理模式](#二、kube-proxy 三种代理模式)
      • [2.1 userspace 模式(第一代)](#2.1 userspace 模式(第一代))
      • [2.2 iptables 模式(第二代)](#2.2 iptables 模式(第二代))
      • [2.3 ipvs 模式(第三代)](#2.3 ipvs 模式(第三代))
      • 三种模式对比
    • [三、Service 类型及实操](#三、Service 类型及实操)
      • [3.1 ClusterIP(默认类型)](#3.1 ClusterIP(默认类型))
        • [3.1.1 普通 ClusterIP Service(命令行创建)](#3.1.1 普通 ClusterIP Service(命令行创建))
        • [3.1.2 普通 ClusterIP Service(YAML 创建)](#3.1.2 普通 ClusterIP Service(YAML 创建))
        • [3.1.3 Headless Service(无头服务)](#3.1.3 Headless Service(无头服务))
      • [3.2 NodePort(外部访问入口)](#3.2 NodePort(外部访问入口))
      • [3.3 LoadBalancer(云厂商负载均衡)](#3.3 LoadBalancer(云厂商负载均衡))
        • [3.3.1 自建集群解决方案:MetalLB](#3.3.1 自建集群解决方案:MetalLB)
          • [版本 1:MetalLB v0.12(基于 ConfigMap 配置)](#版本 1:MetalLB v0.12(基于 ConfigMap 配置))
          • [版本 2:MetalLB v0.15(基于 CRD 配置)](#版本 2:MetalLB v0.15(基于 CRD 配置))
      • [3.4 ExternalName(引入外部服务)](#3.4 ExternalName(引入外部服务))
    • 四、特殊场景配置
      • [4.1 跨命名空间访问](#4.1 跨命名空间访问)
        • [场景:ns1 与 ns2 命名空间互访](#场景:ns1 与 ns2 命名空间互访)
      • [4.2 会话粘黏(Session Affinity)](#4.2 会话粘黏(Session Affinity))
    • 五、总结
  • [Kubernetes Service :从不懂到会用(使用命令行版)](#Kubernetes Service :从不懂到会用(使用命令行版))
    • 前置说明
    • [一、为啥需要 Service?(大白话总结)](#一、为啥需要 Service?(大白话总结))
    • [二、Service 的 "3 种快递分拣方式"(kube-proxy 模式)](#二、Service 的 “3 种快递分拣方式”(kube-proxy 模式))
    • [三、4 种 Service 类型:对应不同 "访问场景"](#三、4 种 Service 类型:对应不同 “访问场景”)
      • [3.1 ClusterIP:只让集群内部访问(比如公司内部用)](#3.1 ClusterIP:只让集群内部访问(比如公司内部用))
        • [操作步骤(以 nginx 为例)](#操作步骤(以 nginx 为例))
          • [第一步:先创建 2 个 nginx "临时工"(Pod)](#第一步:先创建 2 个 nginx “临时工”(Pod))
          • [第二步:创建 "前台"(ClusterIP Service)](#第二步:创建 “前台”(ClusterIP Service))
          • 第三步:测试访问(集群内才能用)
      • [3.2 NodePort:让集群外也能访问(比如你本地电脑访问)](#3.2 NodePort:让集群外也能访问(比如你本地电脑访问))
        • 操作步骤
          • [第一步:还是先有 nginx Pod(同 3.1 第一步,不用重复做)](#第一步:还是先有 nginx Pod(同 3.1 第一步,不用重复做))
          • [第二步:创建 NodePort 类型的 Service](#第二步:创建 NodePort 类型的 Service)
          • 第三步:本地电脑访问
      • [3.3 LoadBalancer:公司级对外访问(用 MetalLB 实现)](#3.3 LoadBalancer:公司级对外访问(用 MetalLB 实现))
        • 操作步骤(小白版,复制粘贴就行)
          • [第一步:安装 MetalLB(负载均衡器工具)](#第一步:安装 MetalLB(负载均衡器工具))
          • [第二步:给 MetalLB 分配 IP(让它有地址可分配)](#第二步:给 MetalLB 分配 IP(让它有地址可分配))
          • [第三步:创建 LoadBalancer 类型的 Service](#第三步:创建 LoadBalancer 类型的 Service)
          • 第四步:访问测试
      • [3.4 ExternalName:让集群内 Pod 访问外部服务(比如访问百度)](#3.4 ExternalName:让集群内 Pod 访问外部服务(比如访问百度))
        • 操作步骤
          • [第一步:创建 ExternalName 类型的 Service](#第一步:创建 ExternalName 类型的 Service)
          • [第二步:测试访问(集群内 Pod 访问)](#第二步:测试访问(集群内 Pod 访问))
    • 四、小白常遇到的问题(避坑指南)
    • [五、总结:小白怎么选 Service 类型?](#五、总结:小白怎么选 Service 类型?)

Kubernetes Service 核心概念与实操指南(使用yaml文件版)

引言

在 Kubernetes 集群中,Pod 具有 "用后即焚" 的特性,IP 地址会随重建频繁变动,导致服务访问不稳定。Service 作为 Pod 的统一访问入口,通过 Label 关联 Pod,动态跟踪 Pod IP 变化,同时提供负载均衡、访问策略定义等核心能力,是 K8s 服务暴露与访问的关键组件。

一、Service 核心作用

  1. 固定访问入口:为 Pod 提供统一的虚拟 IP(ClusterIP),屏蔽 Pod IP 变动影响
  2. 动态关联 Pod:通过 Label Selector 自动关联匹配的 Pod,Pod 增减或 IP 变化时自动更新端点列表(Endpoints)
  3. 负载均衡:支持 TCP/UDP 4 层负载均衡,分发请求到后端多个 Pod
  4. 访问策略定义:控制集群内外对 Pod 的访问规则
  5. 防止 Pod 失联:通过端点监控确保请求仅转发到健康的 Pod

二、kube-proxy 三种代理模式

kube-proxy 是实现 Service 功能的核心组件,通过监控 kube-apiserver 中 Service 和 Endpoints 的变化,在节点上生成转发规则。支持三种代理模式,各有优劣:

2.1 userspace 模式(第一代)

  • 版本支持:K8s v1.0 起支持
  • 核心原理:kube-proxy 为每个 Service 监听随机端口,通过 iptables 规则将 ClusterIP:Port 请求转发到该端口,再由 kube-proxy 采用轮询(默认)或会话亲和性策略分发到 Pod
  • 优缺点:
    • 缺点:请求需在用户态与内核态之间切换,性能损耗大,效率低
    • 优点:实现简单,兼容性好(仅作了解,不推荐使用)

2.2 iptables 模式(第二代)

  • 版本支持:K8s v1.1 起支持,v1.2 起成为默认模式
  • 核心原理:kube-proxy 仅作为控制器,通过 netfilter/iptables 规则直接实现请求转发,无需用户态干预
  • 优缺点:
    • 优点:性能优于 userspace 模式,内核态转发效率高
    • 缺点:规则过多时呈线性匹配延时,转发算法单一(仅轮询、随机)

2.3 ipvs 模式(第三代)

  • 版本支持:K8s v1.8 引入,v1.11 正式可用,v1.11+ 默认推荐
  • 核心原理:基于 Linux 内核 IPVS(IP Virtual Server)模块,提供 4 层负载均衡,通过 ipset 存储地址集合优化规则匹配
  • 核心优势:
    • 支持更丰富的负载均衡算法(最小负载、最少连接、加权轮询等)
    • 规则查找效率高(ipset 为索引结构,而非 iptables 的线性结构)
    • 支持服务器健康检查、连接重试功能
    • 动态修改规则不影响现有连接
  • 依赖:内核版本需 4.0+,需加载 ipvs 模块,否则自动降级为 iptables 模式

三种模式对比

模式 内核态 / 用户态 性能 负载均衡算法 适用场景
userspace 两者切换 轮询、会话亲和 早期版本兼容(不推荐)
iptables 内核态 轮询、随机 小型集群(规则少)
ipvs 内核态 多种算法 中大型集群(推荐)

三、Service 类型及实操

K8s 提供 4 种核心 Service 类型,适配不同访问场景,以下是详细配置与实操步骤:

3.1 ClusterIP(默认类型)

仅集群内部可访问,分配集群唯一虚拟 IP。分为普通 Service 和 Headless Service 两类。

3.1.1 普通 ClusterIP Service(命令行创建)
  1. 先创建 Deployment 应用
yaml 复制代码
# nginx_deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-server1
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: c1
        image: nginx:1.26-alpine
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
  1. 应用 YAML 并验证
bash 复制代码
kubectl apply -f nginx_deployment.yml
# 查看 Pod 和 Deployment
kubectl get pod -o wide
kubectl get deployment.apps
  1. 创建 ClusterIP Service 并关联 Deployment
bash 复制代码
kubectl expose deployment nginx-server1 --type=ClusterIP --target-port=80 --port=80
  1. 验证 Service 与访问
bash 复制代码
# 查看 Service 详情(ClusterIP、Endpoints)
kubectl get svc
kubectl describe service nginx-server1
# 集群内访问(curl ClusterIP)
curl http://10.100.88.200  # 替换为实际 ClusterIP
3.1.2 普通 ClusterIP Service(YAML 创建)
yaml 复制代码
# nginx_service.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-server1
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: c2
        image: nginx:1.26-alpine
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 80        # Service 访问端口
    targetPort: 80  # Pod 容器端口
  selector:
    app: nginx      # 关联 Label 为 app=nginx 的 Pod

应用并验证:

bash 复制代码
kubectl apply -f nginx_service.yml
kubectl get svc,pod
curl http://10.109.23.95  # 替换为实际 ClusterIP
3.1.3 Headless Service(无头服务)
  • 特点:不分配 ClusterIP,不提供负载均衡,通过 DNS 直接解析为后端 Pod IP 列表
  • 适用场景:需要直接访问单个 Pod(如 StatefulSet 应用)

创建 YAML:

yaml 复制代码
# headless-service.yml
apiVersion: v1
kind: Service
metadata:
  name: headless-service
  namespace: default
spec:
  type: ClusterIP
  clusterIP: None  # 关键配置:无头服务标识
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx

应用并验证 DNS 解析:

bash 复制代码
kubectl apply -f headless-service.yml
# 集群内通过 DNS 解析 Pod IP(格式:<service名>.<命名空间>.svc.cluster.local)
dig -t a headless-service.default.svc.cluster.local. @10.96.0.10  # 10.96.0.10 为 kube-dns IP
# 或在 Pod 内访问
kubectl run -it centos --image=centos:7
curl http://headless-service.default.svc.cluster.local

3.2 NodePort(外部访问入口)

在每个 Node 上开放一个固定端口(30000-32767),外部可通过 NodeIP:NodePort 访问服务。

创建 YAML:

yaml 复制代码
# nginx_nodeport.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app
  labels:
    app: nginx-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-app
  template:
    metadata:
      labels:
        app: nginx-app
    spec:
      containers:
      - name: c2
        image: nginx:1.26-alpine
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-app
spec:
  type: NodePort
  ports:
  - protocol: TCP
    nodePort: 31111  # 自定义 NodePort(需在 30000-32767 范围内)
    port: 8060       # Service 内部端口
    targetPort: 80   # Pod 容器端口
  selector:
    app: nginx-app

应用并验证:

bash 复制代码
kubectl apply -f nginx_nodeport.yml
kubectl get svc,pod
# 外部访问(浏览器或 curl)
http://192.168.100.128:31111  # 替换为实际 NodeIP 和 NodePort

3.3 LoadBalancer(云厂商负载均衡)

依赖云厂商(如 AWS、GCP、阿里云)提供的负载均衡服务,自动分配公网 IP,外部通过该 IP 访问服务。

3.3.1 自建集群解决方案:MetalLB

自建 K8s 集群无云厂商 LB 支持,可通过 MetalLB 实现 LoadBalancer 功能,核心提供 IP 地址分配和外部通告(ARP/NDP/BGP)。

版本 1:MetalLB v0.12(基于 ConfigMap 配置)
  1. 下载资源清单
bash 复制代码
wget https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
wget https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml
  1. 应用清单
bash 复制代码
kubectl apply -f namespace.yaml
kubectl apply -f metallb.yaml
# 查看 MetalLB 组件(确保 Running)
kubectl get pod -n metallb-system
  1. 配置 IP 地址池
yaml 复制代码
# metallb-conf.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.100.180-192.168.100.200  # 与集群节点同网段

运行

bash 复制代码
kubectl apply -f metallb-conf.yaml
  1. 创建 Deployment 和 LoadBalancer Service
yaml 复制代码
# nginx-metallb.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-metallb
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx-metallb1
        image: nginx:1.26-alpine
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-metallb
spec:
  type: LoadBalancer
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx

运行

bash 复制代码
kubectl apply -f nginx-metallb.yaml
# 查看 Service(EXTERNAL-IP 为 MetalLB 分配的 IP)
kubectl get svc
# 外部访问
curl http://192.168.100.180  # 替换为实际 EXTERNAL-IP
版本 2:MetalLB v0.15(基于 CRD 配置)
  1. 修改 kube-proxy 配置
bash 复制代码
kubectl edit configmap -n kube-system kube-proxy
# 确保以下配置
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
  strictARP: true
  1. 安装 MetalLB
bash 复制代码
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.2/config/manifests/metallb-native.yaml
  1. 配置 IP 地址池(IPAddressPool CRD)
yaml 复制代码
# ipaddresspool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.18.200-192.168.18.209  # IP 池范围

运行

bash 复制代码
kubectl apply -f ipaddresspool.yaml
kubectl get ipaddresspool -n metallb-system
  1. 创建 Service 并验证(同 v0.12 步骤 4)

3.4 ExternalName(引入外部服务)

将集群外部服务(如公网 API、数据库)通过域名引入集群内部,实现 Pod 与外部服务通信。

创建 YAML:

yaml 复制代码
# externelname.yml
apiVersion: v1
kind: Service
metadata:
  name: my-externalname
  namespace: default
spec:
  type: ExternalName
  externalName: www.baidu.com  # 外部服务域名

应用并验证:

bash 复制代码
kubectl apply -f externelname.yml
# 集群内解析验证
dig -t A my-externalname.default.svc.cluster.local. @10.96.0.10
# Pod 内访问外部服务
kubectl run -it expod --image=busybox:1.28
nslookup my-externalname.default.svc.cluster.local.

四、特殊场景配置

4.1 跨命名空间访问

通过 ExternalName 类型 Service 实现不同命名空间的服务互通。

场景:ns1 与 ns2 命名空间互访
  1. 创建 ns1 资源(Deployment + Headless Service + ExternalName Service)
yaml 复制代码
# ns1-nginx.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: ns1
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx
  namespace: ns1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.26-alpine
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: svc1
  namespace: ns1
spec:
  clusterIP: None  # Headless Service
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx
---
apiVersion: v1
kind: Service
metadata:
  name: external-svc1
  namespace: ns1
spec:
  type: ExternalName
  externalName: svc2.ns2.svc.cluster.local  # 引入 ns2 的 svc2
  1. 创建 ns2 资源(与 ns1 对称,引入 ns1 的 svc1)
yaml 复制代码
# ns2-nginx.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: ns2
---
# 其余 Deployment、svc2、external-svc1 配置与 ns1 一致,仅 externalName 改为 svc1.ns1.svc.cluster.local
  1. 应用并验证
bash 复制代码
kubectl apply -f ns1-nginx.yaml
kubectl apply -f ns2-nginx.yaml
# ns1 Pod 内访问 ns2 服务
kubectl exec -it deploy-nginx-66d785bdb5-2rf6x -n ns1 -- /bin/sh
nslookup svc2.ns2.svc.cluster.local.

4.2 会话粘黏(Session Affinity)

让同一客户端 IP 始终访问同一 Pod(类似 Nginx 的 ip_hash、LVS 的 sh 算法),默认失效时间 3 小时(10800 秒)。

配置步骤:

  1. 创建 Deployment 和 Service
yaml 复制代码
# deployment-nginx-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: c1
        image: nginx:1.26-alpine
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx
  1. 应用并修改 Pod 首页内容(用于区分)
bash 复制代码
kubectl apply -f deployment-nginx-svc.yaml
# 分别修改两个 Pod 的 index.html 为 web1 和 web2
kubectl exec -it nginx-server-5b6d5cd699-8vk6v -- sh -c "echo web1 > /usr/share/nginx/html/index.html"
kubectl exec -it nginx-server-5b6d5cd699-z8t4f -- sh -c "echo web2 > /usr/share/nginx/html/index.html"
  1. 启用会话粘黏
bash 复制代码
# 修改 Service 的 sessionAffinity 为 ClientIP
kubectl patch svc nginx-svc -p '{"spec":{"sessionAffinity":"ClientIP"}}'
# 验证(多次 curl 同一 ClusterIP,返回相同内容)
curl http://10.102.250.195

五、总结

  1. Service 核心价值:解决 Pod IP 动态变化问题,提供稳定访问入口和负载均衡
  2. 模式选型:中大型集群优先使用 ipvs 模式,小型集群可使用 iptables 模式
  3. 类型选型:
    • 集群内访问:ClusterIP(普通 / Headless)
    • 外部简单访问:NodePort
    • 生产环境外部访问:LoadBalancer + MetalLB(自建集群)
    • 集群内外服务互通:ExternalName
  4. 进阶配置:跨命名空间访问、会话粘黏可满足特殊业务需求

Kubernetes Service :从不懂到会用(使用命令行版)

前置说明

先跟小白们同步 2 个基础认知,避免后面懵:

  1. Pod 是啥? 可以理解成 "临时工"------K8s 里跑应用的最小单位,但它很不稳定,比如重启后 IP 会变(就像临时工换了手机号),直接找它干活很麻烦。
  2. Service 是啥? 就是 "前台小姐姐"------ 不管 "临时工"(Pod)怎么换手机号(IP),前台都知道最新联系方式,你要找临时工干活,直接找前台就行,不用管后面谁换了。

一、为啥需要 Service?(大白话总结)

  1. 不用记 Pod 的 IP:Pod 重启 IP 就变,Service 有个固定的 "虚拟手机号"(ClusterIP),记这个就行。
  2. 自动找能用的 Pod:如果多个 Pod 跑同一个应用(比如 2 个 nginx),Service 会自动把请求分给它们,不用你手动选。
  3. 控制谁能访问:比如只让公司内部(集群内)访问,或者允许外面的人(集群外)访问。

二、Service 的 "3 种快递分拣方式"(kube-proxy 模式)

Service 能干活,靠的是一个叫kube-proxy的组件,它有 3 种 "分拣快递" 的方式(转发请求),小白不用深究原理,记 "选哪种" 就行:

模式名字 通俗理解 优点 缺点 推荐场景
userspace 快递先拿进前台再分(慢) 老版本能用 慢,现在基本不用 没人用(了解下)
iptables 直接在仓库分拣(中速) 比第一种快 快递多了会变慢 小集群(几十 Pod)
ipvs 专业分拣机(最快) 快、支持多种分法 需要新一点的系统 中大型集群(推荐)

小白结论 :不用管前两种,默认选ipvs就行,K8s 会自动配置(系统太老会自动用iptables)。

三、4 种 Service 类型:对应不同 "访问场景"

这部分是重点!小白只要搞清楚 "我要让谁访问",就能选对类型。每种类型都带 "场景例子 + 一步一步操作",命令复制粘贴就能用。

3.1 ClusterIP:只让集群内部访问(比如公司内部用)

场景:集群里的 PodA 想访问 PodB 跑的 nginx,不用记 PodB 的 IP,用 Service 的固定地址就行。

操作步骤(以 nginx 为例)
第一步:先创建 2 个 nginx "临时工"(Pod)

先写一个 "工作清单"(YAML 文件),告诉 K8s 要创建 2 个 nginx Pod:

yaml 复制代码
# 文件名:nginx_deploy.yml(随便起,后缀是.yml就行)
apiVersion: apps/v1
kind: Deployment  # 表示要创建"一组Pod"(比如2个nginx)
metadata:
  name: nginx-group  # 这组Pod的名字,随便起
spec:
  replicas: 2  # 要创建2个Pod
  selector:
    matchLabels:
      app: nginx  # 给这组Pod贴个标签:"工种=nginx"
  template:
    metadata:
      labels:
        app: nginx  # 每个Pod都带这个标签,方便Service找
    spec:
      containers:
      - name: nginx-box  # 每个Pod里的"容器名字",随便起
        image: nginx:1.26-alpine  # 用nginx的镜像(类似"软件安装包")
        ports:
        - containerPort: 80  # nginx默认用80端口干活

然后执行命令创建 Pod:

bash 复制代码
# 执行这个命令,K8s会根据上面的清单创建Pod
kubectl apply -f nginx_deploy.yml

# 查看Pod是否创建成功(看到"Running"就是好的)
kubectl get pod
# 成功会显示类似:
# nginx-group-xxxx-xxxx   1/1     Running   0          2m
# nginx-group-xxxx-xxxx   1/1     Running   0          2m
第二步:创建 "前台"(ClusterIP Service)

执行命令创建 Service,让它自动找带 "app=nginx" 标签的 Pod:

bash 复制代码
# 创建Service,类型是ClusterIP,把80端口的请求转发给Pod的80端口
kubectl expose deployment nginx-group --type=ClusterIP --port=80 --target-port=80

# 查看Service信息(重点看"CLUSTER-IP",这是前台的固定地址)
kubectl get svc
# 会显示类似:
# NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
# nginx-group  ClusterIP   10.96.123.45   <none>        80/TCP    1m
第三步:测试访问(集群内才能用)

在 K8s 集群的任意节点(比如 master 节点)执行:

bash 复制代码
# 把10.96.123.45换成你上面看到的CLUSTER-IP
curl http://10.96.123.45
# 成功会显示nginx的欢迎页面(一堆HTML代码)

3.2 NodePort:让集群外也能访问(比如你本地电脑访问)

场景:你在自己的电脑上想打开 K8s 里的 nginx,ClusterIP 只能集群内用,这时候用 NodePort------ 给每个节点开个 "对外窗口"(端口),你用 "节点 IP: 窗口端口" 就能访问。

操作步骤
第一步:还是先有 nginx Pod(同 3.1 第一步,不用重复做)

如果已经有了,直接下一步;没有就执行 3.1 的第一步。

第二步:创建 NodePort 类型的 Service
bash 复制代码
# 创建Service,类型是NodePort,指定窗口端口31234(必须在30000-32767之间)
kubectl expose deployment nginx-group --type=NodePort --port=80 --target-port=80 --node-port=31234

# 查看Service信息(重点看"PORT(S)"里的31234)
kubectl get svc
# 会显示类似:
# NAME         TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
# nginx-group  NodePort   10.96.123.45   <none>        80:31234/TCP   1m
第三步:本地电脑访问
  1. 找一个 K8s 节点的 IP(比如 master 节点的 IP 是 192.168.1.100);
  2. 打开本地浏览器,输入:http://192.168.1.100:31234
  3. 能看到 nginx 的欢迎页面,就成功了!

3.3 LoadBalancer:公司级对外访问(用 MetalLB 实现)

场景 :如果公司用 K8s,想让用户通过一个固定的公网 IP 访问应用,NodePort 的端口太乱,这时候用 LoadBalancer------ 需要一个 "负载均衡器",自建集群用MetalLB这个工具来模拟。

操作步骤(小白版,复制粘贴就行)
第一步:安装 MetalLB(负载均衡器工具)
bash 复制代码
# 1. 创建MetalLB的命名空间(类似"文件夹")
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml

# 2. 安装MetalLB组件
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml

# 3. 查看是否安装成功(看到"Running"就好)
kubectl get pod -n metallb-system
第二步:给 MetalLB 分配 IP(让它有地址可分配)

写一个配置文件,告诉 MetalLB 能用哪些 IP:

yaml 复制代码
# 文件名:metallb_ip.yml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system  # 必须跟MetalLB在同一个"文件夹"
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.1.200-192.168.1.210  # 把这里换成你集群能用的IP段(比如跟节点同网段)

执行命令应用配置:

bash 复制代码
kubectl apply -f metallb_ip.yml
第三步:创建 LoadBalancer 类型的 Service
bash 复制代码
# 创建Service,类型是LoadBalancer
kubectl expose deployment nginx-group --type=LoadBalancer --port=80 --target-port=80

# 查看Service(重点看"EXTERNAL-IP",这是MetalLB分配的固定IP)
kubectl get svc
# 会显示类似:
# NAME         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
# nginx-group  LoadBalancer   10.96.123.45   192.168.1.200 80:31456/TCP   1m
第四步:访问测试

本地浏览器输入http://192.168.1.200(上面的 EXTERNAL-IP),就能看到 nginx 页面,而且这个 IP 是固定的,重启 Pod 也不变!

3.4 ExternalName:让集群内 Pod 访问外部服务(比如访问百度)

场景 :K8s 里的 Pod 想访问百度(www.baidu.com),可以给百度起个 "集群内的小名",比如baidu-in-cluster,Pod 直接访问这个小名就行。

操作步骤
第一步:创建 ExternalName 类型的 Service

写一个配置文件:

yaml 复制代码
# 文件名:baidu_service.yml
apiVersion: v1
kind: Service
metadata:
  name: baidu-in-cluster  # 给百度起的小名
spec:
  type: ExternalName
  externalName: www.baidu.com  # 实际要访问的外部地址

执行命令创建:

bash 复制代码
kubectl apply -f baidu_service.yml

# 查看Service
kubectl get svc
# 会显示类似:
# NAME              TYPE           CLUSTER-IP   EXTERNAL-IP    PORT(S)   AGE
# baidu-in-cluster  ExternalName   <none>       www.baidu.com  <none>    1m
第二步:测试访问(集群内 Pod 访问)

在 K8s 里创建一个临时 Pod,测试能不能通过 "小名" 访问百度:

bash 复制代码
# 创建一个临时的busybox Pod,进去执行命令
kubectl run -it test-pod --image=busybox:1.28 --rm

# 进入Pod后,执行下面的命令(访问百度的小名)
nslookup baidu-in-cluster.default.svc.cluster.local
# 成功会显示百度的IP(比如180.101.49.44)

# 再试一次curl(如果提示curl不存在,不用管,nslookup成功就说明通了)
curl baidu-in-cluster.default.svc.cluster.local

四、小白常遇到的问题(避坑指南)

  1. 执行 kubectl 命令提示 "找不到命令":说明没装 kubectl 工具,先装 kubectl 并配置 K8s 集群连接。
  2. Pod 状态一直是 Pending :可能是集群资源不够(比如 CPU、内存),或者镜像拉不下来(换国内镜像,比如nginx:1.26-alpine换成registry.cn-hangzhou.aliyuncs.com/google_containers/nginx:1.26-alpine)。
  3. 访问 NodePort 时打不开页面 :检查节点的防火墙(比如关闭 firewalld:systemctl stop firewalld),或者端口没在 30000-32767 之间。

五、总结:小白怎么选 Service 类型?

我要做什么? 选哪种 Service? 简单记法
集群内 Pod 之间访问 ClusterIP 内部用
本地电脑访问集群内应用 NodePort 个人测试用
公司用户访问,要固定 IP LoadBalancer 公司生产用
集群内 Pod 访问外部服务(比如百度) ExternalName 连外部用
相关推荐
人工智能训练3 分钟前
Docker Desktop WSL 集成配置宝典:选项拆解 + 精准设置指南
linux·运维·服务器·人工智能·docker·容器·ai编程
伞啊伞31 分钟前
docker作业
运维·docker·容器
野蛮人6号1 小时前
p29 docker08-docker基础-本地目录挂载 无法正确添加mysql 点击更新后data没有正常显示
mysql·docker·容器
峰顶听歌的鲸鱼2 小时前
15.docker:网络
运维·网络·docker·容器·云计算·php·学习方法
遇见火星3 小时前
Docker Compose 实战教程,理解Docker Compose核心概念,学会编写 compose.yml,掌握常用命令!
运维·docker·容器·compose
原神启动13 小时前
Docker(二)—— Docker容器操作
运维·docker·容器
你什么冠军?3 小时前
Docker
运维·容器
呼啦啦呼啦啦啦啦啦啦3 小时前
推送docker镜像至私有 Docker 镜像仓库(附企业harbor实战)
运维·docker·容器
m0_485614673 小时前
Docker基础
docker·容器·php
爱学大树锯3 小时前
【Docker本地化超级实践】Docker 镜像离线构建方案
运维·docker·容器