k8s service 一些零散的特性

Service分发负载的策略

大家都知道,一个service可以对应多个pod,那么一定要有一些方法来把service接收到的请求(负载)转发到pod上。
一般来说,有两种策略,一种是轮询,还有一种会话状态保持。

轮询策略很简单,就不多说了,这也是service的默认策略,在不做什么相关配置的情况下就是使用轮询策略的。

这里讲一下会话状态保持策略,下面先给出一个具体的例子,然后再对其作解释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
sessionAffinity: ClientIP
sessionAffinityConfig:
ClientIP:
timeoutSeconds: 10800
selector:
app.kubernetes.io/name: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376

主要是sessionAffinity和sessionAffinityConfig这两个参数。
sessionAffinity配置为ClientIP表示根据请求的source ip把来自同一个IP的请求分发到同一个pod上。
sessionAffinityConfig.ClientIP.timeoutSeconds表示超时时间,默认是10800。

老实说,现在的应用很多都是基于jwt做认证的,基于session的不是非常多,尤其是新项目中。jwt是不需要做会话状态保持的,但是这个策略对于那些基于session做认证的应用还是很重要的。


同一端口通过不同协议暴露

最近第一次发现了一个新的用法,就是同一个端口用不同的协议暴露,比如53端口,同时通过TCP和UDP进行暴露,下面是具体的yaml配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1 
kind: Service
metadata:
name: kube-dns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "KubeDNS"
spec:
selector:
k8s-app: kube-dns
clusterIP: 169.169.0.100
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP

老实说,这种用法很少见,我从2019年开始使用k8s,从来没在项目中见过这种使用方法,但是存在既有道理,做个记录吧,也加深自己的印象。

Headless Service的负载分发策略

直观上看,headless service跟普通service最大的区别就是没有ClusterIP。这是对的,但是更正确的说,headless service跟普通service的区别是它不提供负载均衡的功能。

前面说过,service有轮询和会话状态保持两种负载均衡策略。headless service特点是,在有客户端请求的时候,它通过label selector把所有匹配的pod都返回给客户端,让客户端自己决定访问哪一个pod。

StatefulSet就是通过headless service向客户端返回多个可用的地址。