Service
Service 介绍
- Service,能够为客户端应用提供稳定的访问地址(域名或者IP地址)和负载均衡功能,以及屏蔽后端Endpoint的变化,是kubernetes实现微服务的核心资源
Service 访问实现原理
iptables 代理模式
- kube-proxy 通过设置 Linux 内核的 防火墙规则,实现从Service到后端Endpoint 列表的负载分发规则,效率很高。
- 原理图
ipvs 代理模式
- kube-proxy 通过设置 Linux 内核的netlink接口设置IPVS规则,转发效率和支持的吞吐率都是最高的
- ipvs模式支持更多的负载均衡策略
- rr: 轮训
- lc:最小连接数
- dh:目的地址哈希
- sh:源地址哈希
- sed:最短期望延时
- nq:永不排队
- 原理图
userspace 代理模式(早期版本)
- 用户空间模式,由kube-proxy完成代理的实现,效率较低(不在推荐)
- 原理图
kernelspace 模式
- Windows Server 上的代理模式
会话保持机制
- Service 支持通过设置 sessionAffinity 实现基于客户端IP的会话保持机制
[root@master nginx]# cat webnginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp
namespace: test-nginx
spec:
sessionAffinity: ClientIP #设置会话保持
sessionAffinityConfig: #设置会话保持的最长时间
ClientIP:
timeoutSeconds:18000
ports:
- protocol: TCP
port: 8080
targetPort: 80
selector:
app: webapp
Service 多端口设置
[root@master nginx]# cat webnginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp
namespace: test-nginx
spec:
ports:
- port: 8080 #service 端口
targetPort: 80 #后端pod的容器端口
name: web
- port: 8081 #service 端口
targetPort: 80 #后端pod的容器端口
name: apache
selector: #定义后端Pod所拥有的label
app: webapp
# 使用不同的协议
[root@master nginx]# cat webnginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: kube-dns
namespace: kube-system
spec:
selector:
k8s-app: kube-dns
ClientIP: 169.169.0.100
ports:
- name: dns
port: 53
protocol: TCP
- name: dns-UDP
port: 53
protocol: UDP
Service 对外访问
-
Kubernets 提供了多种机制将Service暴露出去,供集群外部的客户端访问
-
Service 类型如下
- ClusterIP
Kubernetes 默认会自动设置Service的虚拟IP地址,仅可被集群内部的客户端应用访问
- NodePort
- LoadBalance
- ExternalName
- NodePort 类型示例
[root@master nginx]# cat webnginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp
namespace: test-nginx
spec:
type: NodePort
ports:
- port: 8080
targetPort: 80
nodePort: 8081 #如果不设置nodePort端口号,则kubernets会自动分配一个NodePort范围内的可用端口号
selector: #定义后端Pod所拥有的label
app: webapp
- LoadBalance 类型示例
#客户端通过 负载均衡的IP和Service的端口号就可以访问到具体的服务,无须在通过kube-proxy提供的负载均衡机制进行流量转发
[root@master nginx]# cat webnginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp
namespace: test-nginx
spec:
type: LoadBalancer
ports:
- protocol: TCP
port: 80
targetPort: 9376
clusterIP: 10.11.199.247
selector:
app: webapp
#Service创建后,Service会补充LoadBalancer的IP地址
status:
loadBalancer:
ingress:
- ip:1.1.1.1
- ExternalName 类型示例
#将Service映射为一个外部域名地址,通过ExternalName字段进行设置
[root@master nginx]# cat webnginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp
namespace: test-nginx
spec:
type: ExternalName
externalName: my.date.example.com
Service 支持的网络协议
- 支持的协议如下:
- TCP:Service 默认的网络协议
- UDP:可用于大多数的Service
- HTTP:取决于云服务商是否支持
- PROXY:取决于云服务商是否支持
- STCP:1.12版本之后引入,默认开启
Service服务发现机制
- 环境变量 方式
在Pod运行时,系统会自动为容器运行环境注入所有集群中有效的Service信息,包含:服务IP,服务端口号等,通过{SVCNAME}_SERVICE_HOST 和 {SVCNAME}_SERVICE_PORT格式进行设置
[root@master nginx]# cat webnginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp
namespace: test-nginx
spec:
ports:
- protocol: TCP
port: 8080 #service 端口
targetPort: 80 #后端pod的容器端口
selector: #定义后端Pod所拥有的label
app: webapp
#WEBAPP_SERVICE_HOST=10.11.199.247
#WEBAPP_SERVICE_PORT=8080
#WEBAPP_PORT=tcp://1.1.1.1:80
- DNS 方式
#Service的DNS域名表示方法为<servicename>.<namespace>.svc.<clusterdomain>
$ servicename 为服务的名称
$ namespace 为namespace名称
$ clusterdomain 为kubernetes集群设置的域名后缀
Headless Service 概念
- 概念:服务没有入口访问地址,kube-proxy不会为其创建负载转发规则,而服务名(DNS域名)的 解析机制取决于该Headless Service是否设置了Label Selector
- Headless Service
- 如果设置了Label Selector, Kubernetes会根据 Label Selector 查询后端Pod列表,自动创建Endpoint,将服务名(DNS域名)的解析机制设置为:当客户端访问该服务是,得到的是全部Endpoint列表
- 如果没有设置Label Selector,Kubernetes 则不会创建Endpoint列表
Ingress 7层路由机制
- Ingress资源对象,用于将不同URL的访问请求转发到后端不同的Service,以实现HTTP层的业务路由机制
- Kubernetes使用一个Ingress策略定义和一个具体的Ingress Controller,两者结合并实现了一个完整的Ingress负载均衡器
-
架构图
- 示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx
annotations:
# use the shared ingress-nginx
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: a.com #基于域名的访问,客户端请求将作用于指定域名的客户端请求
http:
paths: #一组根据路径进行转发的规则设置
- path: /
pathType: Prefix
backend: #目标后端服务,包括服务的名称和端口
service:
name: nginx
port:
number: 80
# 如果一个请求同时被多个URL路径匹配,系统将以最长的匹配路径优先。如果长度相同,则精确匹配类型优先前缀匹配类型
Service简单示例
- 创建两个nginx pod
#创建namespace
[root@master nginx]# cat nginxnamespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test-nginx
labels:
name: test-nginx
#创建deployment
[root@master nginx]# cat webnginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
namespace: test-nginx
spec:
replicas: 2
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: nginx:1.22
ports:
- containerPort: 80
#创建pod
$kubectl apply -f nginxnamespace.yaml
$kubectl apply -f webnginx.yaml
- 创建service
#快速创建
$ kubectl expose deployment webapp
#yaml创建
[root@master nginx]# cat webnginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp
namespace: test-nginx
spec:
ports:
- protocol: TCP
port: 8080 #service 端口
targetPort: 80 #后端pod的容器端口
selector: #定义后端Pod所拥有的label
app: webapp
[root@master nginx]# kubectl get svc -n test-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
webapp ClusterIP 10.11.199.247 <none> 8080/TCP 3m13
[root@master nginx]# curl -Lvo /dev/null 10.11.199.247:8080
* About to connect() to 10.11.199.247 port 8080 (#0)
* Trying 10.11.199.247...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 10.11.199.247 (10.11.199.247) port 8080 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 10.11.199.247:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.22.0
< Date: Sat, 30 Jul 2022 16:31:33 GMT
< Content-Type: text/html
< Content-Length: 615
< Last-Modified: Mon, 23 May 2022 23:59:19 GMT
< Connection: keep-alive
< ETag: "628c1fd7-267"
< Accept-Ranges: bytes
<
- 查看service 详细信息
[root@master nginx]# kubectl describe svc webapp -n test-nginx
Name: webapp
Namespace: test-nginx
Labels: <none>
Annotations: <none>
Selector: app=webapp
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.11.199.247
IPs: 10.11.199.247
Port: <unset> 8080/TCP
TargetPort: 80/TCP
Endpoints: 10.244.104.3:80,10.244.104.4:80
Session Affinity: None
Events: <none>
- Kubernetes 自动创建了与Service关联的Endpoint资源对象,这可以通过查询endpoint对象进行查看
[root@master nginx]# kubectl get endpoints -n test-nginx
NAME ENDPOINTS AGE
webapp 10.244.104.3:80,10.244.104.4:80 8m16s