目录
一、Service介绍


Service 是 Kubernetes 中用于定义一组 Pod 的逻辑集合及其访问策略的抽象。主要解决以下问题:
-
服务发现:动态 Pod 环境下,如何找到其他服务。
-
负载均衡:将流量均匀分发到多个 Pod 实例。
-
解耦访问:客户端无需关心 Pod 的具体 IP 或节点位置。
-
稳定访问端点:Pod 可能频繁重建,Service 提供固定访问入口(ClusterIP/DNS)。
二、Service的核心原理
1、kube-proxy:负责实现 Service 的流量转发,支持以下模式:
-
iptables(默认):通过 iptables 规则转发流量。
-
IPVS:高性能模式,基于内核的 IPVS 负载均衡。
-
userspace(已弃用):用户空间代理。
2、Endpoints:Service 通过标签选择器(Selector)动态维护后端 Pod 的 IP 列表(Endpoints 对象)。
3、EndpointSlice:替代 Endpoints 的扩展机制,支持更大规模的服务(分片存储 Endpoint 信息)。
三、Service常见的三种类型
ClusterIP :默认值,它是 Kubernetes 系统自动 分配的虚拟IP ,只能在 集群内部访问NodePort :将 Service 通过指定的 Node 上的 端口暴露 给外部,通过此方法,就可以在集群外部访问服务LoadBalancer :使用 外接负载均衡器 完成到服务的负载分发,注意此模式需要外部云环境支持
Service的资源清单文件:
kind: Service # 资源类型
apiVersion: v1 # 资源版本
metadata: # 元数据
name: service # 资源名称
namespace: dev # 命名空间
spec: # 描述
selector: # 标签选择器,用于确定当前service代理哪些pod
app: nginx
type: # Service类型,指定service的访问方式
clusterIP: # 虚拟服务的ip地址
sessionAffinity: # session亲和性,支持ClientIP、None两个选项
ports: # 端口信息
- protocol: TCP
port: 3017 # service端口
targetPort: 5003 # pod端口
nodePort: 31122 # 主机端口
实验环境准备:
创建一个deployment.yaml文件,内容如下:
[root@k8s-master test]# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pc-deployment
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
#创建
[root@k8s-master test]# kubectl create -f deployment.yaml
#查看详情
[root@k8s-master test]# # kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pc-deployment-575f6f4ff-7p8hs 1/1 Running 0 36m 100.125.152.6 k8s-node02 <none> <none>
pc-deployment-575f6f4ff-lhqj4 1/1 Running 0 36m 100.97.125.7 k8s-node01 <none> <none>
pc-deployment-575f6f4ff-mvnrp 1/1 Running 0 36m 100.97.125.8 k8s-node01 <none> <none>
#为了后面的测试,修改三台nginx的index.html页面(三台修改的IP地址不一样)
kubectl exec -it pc-deployment-575f6f4ff-7p8hs -n dev /bin/sh
# echo "`hostname`" > /usr/share/nginx/html/index.html
修改完毕,访问测试:
1、ClusterIP
默认类型,为集群内部提供访问的虚拟 IP(仅在集群内可访问)
Kubernetes 中 Deployment 仅管理 Pod 副本,需通过 Service 暴露 Pod 服务,否则外部无法访问。
如果写yaml不太熟练的话,可以执行以下命令导入一个文件中:
[root@k8s-master test]# kubectl create service clusterip nginx-svc1 --tcp=80:80 -n dev --dry-run=client -o yaml > service-clusterip.yaml
[root@k8s-master test]# cat service-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
name: service-clusterip
namespace: dev
spec:
selector:
app: nginx-pod
clusterIP: 10.96.1.100 # service的ip地址,如果不写(删掉),就会默认生成一个IP地址
type: ClusterIP
ports:
- port: 80 # Service端口
targetPort: 80 # pod端口
# 创建 service[root@k8s-master test]# kubectl create -f service-clusterip.yamlservice / service-clusterip created# 查看 service[root@k8s-master test]# kubectl get svc -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service-clusterip ClusterIP 10.96.1.100 <none> 80/TCP 2s app=nginx-pod
2、NodePort
在 ClusterIP 基础上,在每个节点上开放一个静态端口(NodeIP:NodePort)
[root@k8s-master test]# cat service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: service-nodeport
namespace: dev
spec:
selector:
app: nginx-pod
type: NodePort
ports:
- port: 80 # Service端口
nodePort: 30002
targetPort: 80 # pod端口
# 创建service
[root@master ~]# kubectl create -f service-nodeport.yaml
service/service-nodeport created
# 查看service
[root@master ~]# kubectl get svc -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service-headliness ClusterIP None <none> 80/TCP 9m10s app=nginx-pod
service-nodeport NodePort 10.96.1.99 <none> 80:30002/TCP 18s app=nginx-pod
# 接下来可以通过电脑主机的浏览器去访问集群中任意一个nodeip的30002端口,即可访问到pod
3、LoadBalancer
通过云提供商的负载均衡器(如 OpenELB、MetalLB、PureLB)暴露服务到外部。
LoadBalancer和NodePort很相似,目的都是向外部暴露一个端口,区别在于LoadBalancer会在集群的外部再来做一个负载均衡设备,而这个设备需要外部环境支持的,外部服务发送到这个设备上的请求,会被设备负载之后转发到集群中。
不分配 ClusterIP,直接访问 Pod 的 IP 或通过 DNS 解析,客户端需要自行实现负载均衡。
三款开源 Kubernetes 负载均衡器: MetalLB vs PureLB vs OpenELB
apiVersion: v1
kind: Service
metadata:
name: my-loadbalancer-service
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
externalTrafficPolicy: Local # 保留客户端源 IP(默认是 Cluster)
OpenELB应用的安装和部署
3.1、安装OpenELB
前提是为 kube-proxy 启用 strictARP ,以便 Kubernetes 集群中的所有网卡停止响应其他网卡的
[root@k8s-master ~]# kubectl edit configmap kube-proxy -n kube-system
configmap/kube-proxy edited
安装: (可能下载不下来,需要开代理)
# wget -c https://raw.githubusercontent.com/openelb/openelb/master/deploy/openelb.yaml修改镜像地址:修改两处image: k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1 为 image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1[root@k8s-master ~]# kubectl apply -f openelb.yaml![]()
3.2、添加 EIP 池
[root@k8s-master ~]# vim ip_pool.yml
apiVersion: network.kubesphere.io/v1alpha2
kind: Eip
metadata:
name: eip-pool
spec:
address: 192.168.8.200-192.168.8.230
protocol: layer2
disable: false
interface: ens33
[root@k8s-master ~]#
3.3、配置 Service 为 LoadBalancer
把 Service 类型修改为 LoadBalancer,同时 annotations 中添加如下三行:lb.kubesphere.io/v1alpha1: openelbprotocol.openelb.kubesphere.io/v1alpha1: layer2eip.openelb.kubesphere.io/v1alpha2: layer2-eip
[root@k8s-master ~]# vimt svc-lb.yml
apiVersion: v1
kind: Service
metadata:
name: svc-lb
namespace: dev
annotations:
lb.kubesphere.io/v1alpha1: openelb
protocol.openelb.kubesphere.io/v1alpha1: layer2
eip.openelb.kubesphere.io/v1alpha2: eip-pool
spec:
selector:
app: nginx-pod
type: LoadBalancer
ports:
- port: 80
targetPort: 80