k8s service 多种类型 types 测试手记 -凯发k8网页登录

记录工作/学习的点点滴滴。

k8s service 多种类型 types 测试手记

前言

这里基于whoami示范服务,部署3个实例,分别一一验证各种类型的k8s service服务范畴。

大致逐一从下面列表逐一验证每种类型的service访问方式:

  • service name
  • 域名解析结果等
  • cluster-ip
  • external-ip

一些设定如下:

  • 测试环境k8s版本号为v1.27.3
  • k8s集群node节点ip地址段范围:10.0.1.0/24
  • k8s集群自动生成pod网段为10.43.0.0/24
  • 本书所列代码皆可拷贝直接粘贴到终端界面直接运行

首先,部署whoami服务

先部署包含3个实例的whoami

# cat << 'eof' | kubectl apply -f -
apiversion: apps/v1
kind: deployment
metadata:
  name: whoami
  labels:
    app: whoami
spec:
  replicas: 3
  selector:
    matchlabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
      - name: whoami
        image: containous/whoami
        ports:
        - containerport: 80
          name: web
eof

查看一下:

# kubectl get all
name                                                      ready   status      restarts         age
pod/whoami-767d459f67-qffqw                               1/1     running     0                23m
pod/whoami-767d459f67-xdv9p                               1/1     running     0                23m
pod/whoami-767d459f67-gwpgx                               1/1     running     0                23m
name                                                  ready   up-to-date   available   age
deployment.apps/whoami                                3/3     3            3           23m
name                                                            desired   current   ready   age
replicaset.apps/whoami-767d459f67                               3         3         3       23m

其次,安装busybox进行调试

安装一个包含有curl的busybox方便后续调试:

kubectl run busybox-curl --image=yauritux/busybox-curl --command -- sleep 3600

另起一个终端,输入下面命令进入:

kubectl exec -ti busybox-curl -n default -- sh

环境准备好之后,下面逐一测试各种类型:

默认cluster ip模式

k8s默认service为cluster ip模式,面向内部pod以及通过ingress对外提供服务。

下面一张图很清晰解释清楚了porttargetport适用情景,port为service对外输出的端口,targetport为服务后端pod的端口,两者之间有一个转换:port -> targetport -> containerport

创建一个service:

cat << 'eof' | kubectl apply -f -
apiversion: v1
kind: service
metadata:
  labels:
    name: whoami-clusterip
  name: whoami-clusterip
spec:
  ports:
  - port: 80
    targetport: 80
    protocol: tcp
  selector:
    app: whoami
eof

部署后可以查看一下:

name                          type           cluster-ip      external-ip   port(s)        age
service/whoami-clusterip      clusterip      10.43.247.74            80/tcp         57s

下面就需要逐一测试了。

域名形式:

# curl whoami-clusterip
hostname: whoami-767d459f67-gwpgx
ip: 127.0.0.1
ip: 10.42.8.35
remoteaddr: 10.42.9.32:35968
get / http/1.1
host: whoami-clusterip
user-agent: curl/7.81.0
accept: */*

cluster ip形式:

# curl 10.43.247.74
hostname: whoami-767d459f67-qffqw
ip: 127.0.0.1
ip: 10.42.3.73
remoteaddr: 10.42.9.32:42398
get / http/1.1
host: 10.43.247.74
user-agent: curl/7.81.0
accept: */*

域名解析,只解析到cluster ip上:

# nslookup whoami-clusterip
server:		10.43.0.10
address:	10.43.0.10:53
name:	whoami-clusterip.default.svc.cluster.local
address: 10.43.247.74

external ip模式

原理同cluster ip模式,为指定服务绑定一个额外的一个ip地址。当终端访问该ip地址,将流量一样转发到service。

当访问external ip,其端口转换过程:port -> targetport -> containerport

与默认service相比,端口转换流程没有增加,但好处对外暴露了一个可访问的ip地址,不过可能需要在交换机/路由器层面提供动静态路由支持。

cat << 'eof' | kubectl apply -f -
apiversion: v1
kind: service
metadata:
  labels:
    name: whoami-externalip
  name: whoami-externalip
spec:
  ports:
  - port: 80
    targetport: 80
    protocol: tcp
  selector:
    app: whoami
  externalips:
  - 10.10.10.10
eof

服务显示如下,绑定了指定的扩展ip地址10.10.10.10

# name                          type           cluster-ip      external-ip   port(s)        age
service/whoami-externalip     clusterip      10.43.192.118   10.10.10.10   80/tcp         57s

kube-proxy 将在每一个node节点为10.10.10.10上建立一个转发规则,该ip地址的80端口将直接转发到对应的后端三个whoami pod 上。

-a kube-services -d 10.10.10.10/32 -p tcp -m comment --comment "default/whoami-externalip external ip" -m tcp --dport 80 -j kube-ext-qn5hievyupdp6unk
......
-a kube-ext-qn5hievyupdp6unk -j kube-svc-qn5hievyupdp6unk
......
-a kube-svc-qn5hievyupdp6unk ! -s 10.42.0.0/16 -d 10.43.192.118/32 -p tcp -m comment --comment "default/whoami-externalip cluster ip" -m tcp --dport 80 -j kube-mark-masq
-a kube-svc-qn5hievyupdp6unk -m comment --comment "default/whoami-externalip -> 10.42.2.79:80" -m statistic --mode random --probability 0.33333333349 -j kube-sep-jsat6d2kfcsf4ylf
-a kube-svc-qn5hievyupdp6unk -m comment --comment "default/whoami-externalip -> 10.42.3.77:80" -m statistic --mode random --probability 0.50000000000 -j kube-sep-2r66ui3g2ay2imnm
-a kube-svc-qn5hievyupdp6unk -m comment --comment "default/whoami-externalip -> 10.42.8.42:80" -j kube-sep-zhhil2san2g37gcm

访问域名:

# curl whoami-externalip
hostname: whoami-767d459f67-gwpgx
ip: 127.0.0.1
ip: 10.42.8.35
remoteaddr: 10.42.9.32:46746
get / http/1.1
host: whoami-externalip
user-agent: curl/7.81.0
accept: */*

访问clusterip形式:

# curl 10.43.192.118
hostname: whoami-767d459f67-qffqw
ip: 127.0.0.1
ip: 10.42.3.73
remoteaddr: 10.42.9.32:47516
get / http/1.1
host: 10.43.192.118
user-agent: curl/7.81.0
accept: */*

访问暴露的external ip:

# curl 10.10.10.10
hostname: whoami-767d459f67-gwpgx
ip: 127.0.0.1
ip: 10.42.8.35
remoteaddr: 10.42.9.0:38477
get / http/1.1
host: 10.10.10.10
user-agent: curl/7.81.0
accept: */*

域名解析结果只解析到其对应的cluster ip:

# nslookup whoami-externalip
server:		10.43.0.10
address:	10.43.0.10:53
name:	whoami-externalip.default.svc.cluster.local
address: 10.43.192.118

nodeport 模式

cluster ip相比,多了一个nodeport,这个nodeport会在k8s所有node节点上都会开放。

这里有一个端口转换过程:nodeport -> port -> targetport -> containerport,多了一层数据转换过程。

服务定义如下:

cat << 'eof' | kubectl apply -f -
apiversion: v1
kind: service
metadata:
  labels:
    name: whoami-nodeport
  name: whoami-nodeport
spec:
  type: nodeport
  ports:
  - port: 80
    targetport: 80
    nodeport: 30080
    protocol: tcp
  selector:
    app: whoami
eof

查看一下服务分配地址:

name                          type           cluster-ip      external-ip   port(s)        age
service/whoami-nodeport       nodeport       10.43.215.233           80:30080/tcp   57s

访问域名:

# curl whoami-nodeport
hostname: whoami-767d459f67-xdv9p
ip: 127.0.0.1
ip: 10.42.2.75
remoteaddr: 10.42.9.32:36878
get / http/1.1
host: whoami-nodeport
user-agent: curl/7.81.0
accept: */*

测试 cluster ip :

# curl 10.43.215.233
hostname: whoami-767d459f67-qffqw
ip: 127.0.0.1
ip: 10.42.3.73
remoteaddr: 10.42.9.32:40552
get / http/1.1
host: 10.43.215.233
user-agent: curl/7.81.0
accept: */*

因为是在每一个k8s node节点上都会开放一个30080端口,因此可以这样访问 {node ip}:{nodeport},如下node ip地址为10.0.1.11

# curl 10.0.1.11:30080
hostname: whoami-767d459f67-qffqw
ip: 127.0.0.1
ip: 10.42.3.73
remoteaddr: 10.42.1.0:1880
get / http/1.1
host: 10.0.1.11:30080
user-agent: curl/7.81.0
accept: */*

域名还是只解析到对应cluster ip:

# nslookup whoami-nodeport
server:		10.43.0.10
address:	10.43.0.10:53
name:	whoami-nodeport.default.svc.cluster.local
address: 10.43.215.233

loadbalancer 模式

loadbalancer模式,会强制k8s service自动开启nodeport

这里有一张图,详细解析数据流向。

服务数据端口转换过程:port -> nodeport -> port -> targetport -> containerport

  • 与默认cluster ip相比,多了两层数据转换过程
  • nodeport相比,对了一层数据转换过程
  • externalip相比,在小流量场景下就没有什么优势了

具体服务定义:

cat << 'eof' | kubectl apply -f -
apiversion: v1
kind: service
metadata:
  labels:
    name: whoami-clusterip-none
  name: whoami-clusterip-none
spec:
  clusterip: none
  ports:
  - port: 80
    targetport: 80
    protocol: tcp
  selector:
    app: whoami
eof

查看一下部署结果:

name                          type           cluster-ip      external-ip   port(s)        age
service/whoami-loadbalancer   loadbalancer   10.43.63.92          80:30906/tcp   57s

服务域名形式:

# curl whoami-loadbalancer
hostname: whoami-767d459f67-qffqw
ip: 127.0.0.1
ip: 10.42.3.73
remoteaddr: 10.42.9.32:57844
get / http/1.1
host: whoami-loadbalancer
user-agent: curl/7.81.0
accept: */*

测试 cluster-ip

# curl 10.43.63.92
hostname: whoami-767d459f67-xdv9p
ip: 127.0.0.1
ip: 10.42.2.75
remoteaddr: 10.42.9.32:42400
get / http/1.1
host: 10.43.63.92
user-agent: curl/7.81.0
accept: */*

域名解析到cluster ip:

#  nslookup whoami-loadbalancer
server:		10.43.0.10
address:	10.43.0.10:53
name:	whoami-loadbalancer.default.svc.cluster.local
address: 10.43.63.92

安装loadbalancer

此时whoami-loadbalancer服务对应的external-ip,我们需要安装一个负载均衡器,可以选择metallb作为负载均衡器。

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

稍后分配可用的loadbalaner可分配的地址池:

cat << 'eof' | kubectl apply -f -
apiversion: metallb.io/v1beta1
kind: ipaddresspool
metadata:
  name: default-pool
  namespace: metallb-system
spec:
  addresses:
  - 10.0.1.100-10.0.1.200
---
apiversion: metallb.io/v1beta1
kind: l2advertisement
metadata:
  name: default
  namespace: metallb-system
spec:
  ipaddresspools:
  - default-pool
eof

等安装完成之后,可以看到服务whoami-loadbalancer分配的ip地址为 10.0.1.101

name                          type           cluster-ip      external-ip   port(s)        age
......
service/whoami-loadbalancer loadbalancer   10.43.63.92     10.0.1.101         80:30906/tcp   27h
......

测试负载均衡ip地址

测试一下:

# curl 10.0.1.101
hostname: whoami-767d459f67-xdv9p
ip: 127.0.0.1
ip: 10.42.2.78
remoteaddr: 10.42.8.0:33658
get / http/1.1
host: 10.0.1.101
user-agent: curl/7.79.1
accept: */*

我们看到该服务分配的端口为80:30906/tcp30906为k8s为该服务自动生成的nodeport类型端口。

可以找任一k8s node节点ip地址测试一下:

# curl 10.0.1.12:30906
hostname: whoami-767d459f67-qffqw
ip: 127.0.0.1
ip: 10.42.3.77
remoteaddr: 10.42.2.0:9717
get / http/1.1
host: 10.0.1.12:30906
user-agent: curl/7.81.0
accept: */*

分析一下路由表,可以分析到该负载均衡的external_ip:80的打流量到nodeport:30906上,然后走service对应{pod:80}流量分发逻辑。

-a kube-nodeports -p tcp -m comment --comment "default/whoami-loadbalancer" -m tcp --dport 30906 -j kube-ext-nbtybeexaczi7dpc
......
-a kube-services -d 10.0.1.101/32 -p tcp -m comment --comment "default/whoami-loadbalancer loadbalancer ip" -m tcp --dport 80 -j kube-ext-nbtybeexaczi7dpc
......
-a kube-ext-nbtybeexaczi7dpc -m comment --comment "masquerade traffic for default/whoami-loadbalancer external destinations" -j kube-mark-masq
-a kube-ext-nbtybeexaczi7dpc -j kube-svc-nbtybeexaczi7dpc
......
-a kube-svc-nbtybeexaczi7dpc ! -s 10.42.0.0/16 -d 10.43.63.92/32 -p tcp -m comment --comment "default/whoami-loadbalancer cluster ip" -m tcp --dport 80 -j kube-mark-masq
-a kube-svc-nbtybeexaczi7dpc -m comment --comment "default/whoami-loadbalancer -> 10.42.2.79:80" -m statistic --mode random --probability 0.33333333349 -j kube-sep-e3k3suynfwt2vice
-a kube-svc-nbtybeexaczi7dpc -m comment --comment "default/whoami-loadbalancer -> 10.42.3.77:80" -m statistic --mode random --probability 0.50000000000 -j kube-sep-hg5myvvid7gjoza7
-a kube-svc-nbtybeexaczi7dpc -m comment --comment "default/whoami-loadbalancer -> 10.42.8.42:80" -j kube-sep-gfjh72ycbkbfb6og

headless 无头模式

一般应用在有状态的服务,或需要终端调用者自己实现负载均衡,等一些特定场景。

通过调用者从端口角度分析,数据转换流程:targetport -> containerport

在意服务性能的场景,不妨试试无头模式。


服务定义:
cat << 'eof' | kubectl apply -f -
apiversion: v1
kind: service
metadata:
  labels:
    name: whoami-clusterip-none
  name: whoami-clusterip-none
spec:
  clusterip: none
  ports:
  - port: 80
    targetport: 80
    protocol: tcp
  selector:
    app: whoami
eof

查看服务部署情况:

name                          type           cluster-ip      external-ip   port(s)        age
service/whoami-clusterip-none   clusterip      none                                 80/tcp         9h

通过service域名访问,k8s会自动根据服务域名whoami-clusterip-none进行pick后端对应pod ip地址。

# curl whoami-clusterip-none
hostname: whoami-767d459f67-xdv9p
ip: 127.0.0.1
ip: 10.42.2.75
remoteaddr: 10.42.9.32:34998
get / http/1.1
host: whoami-clusterip-none
user-agent: curl/7.81.0
accept: */*

查询dns会把所有节点都列出来。

# nslookup whoami-clusterip-none
server:		10.43.0.10
address:	10.43.0.10:53
name:	whoami-clusterip-none.default.svc.cluster.local
address: 10.42.3.73
name:	whoami-clusterip-none.default.svc.cluster.local
address: 10.42.2.75
name:	whoami-clusterip-none.default.svc.cluster.local
address: 10.42.8.35

external name模式

用于引进带域名的外部服务,这里引入内部服务作为测试。

多了一层域名解析过程,端口转换流程依赖于所引入服务的服务设定。

服务定义:

cat << 'eof' | kubectl apply -f -
apiversion: v1
kind: service
metadata:
  labels:
    name: whoami-externalname
  name: whoami-externalname
spec:
  type: externalname
  externalname: whoami-clusterip.default.svc.cluster.local
eof

这里外联的是whoami-clusterip服务的完整访问域名。

查看服务部署情况:

name                          type           cluster-ip      external-ip   port(s)        age
service/whoami-externalname     externalname             whoami-clusterip.default            9h

根据域名访问测试:

# curl whoami-externalname
hostname: whoami-767d459f67-qffqw
ip: 127.0.0.1
ip: 10.42.3.77
remoteaddr: 10.42.9.35:36756
get / http/1.1
host: whoami-externalname
user-agent: curl/7.81.0
accept: */*

dns解析结果:

# nslookup whoami-externalname
server:		10.43.0.10
address:	10.43.0.10:53
whoami-externalname.default.svc.cluster.local	canonical name = whoami-clusterip.default.svc.cluster.local
name:	whoami-clusterip.default.svc.cluster.local
address: 10.43.247.74

小结

简要分析了各种类型service定义、服务引用场景以及测试流程等,整理清楚了,也方便在具体业务场景中进行抉择选择具体服务类型。

posted on 2023-09-13 10:13 nieyong 阅读(113) 评论(0)  编辑  收藏 所属分类: 容器


只有注册用户后才能发表评论。


网站导航:
              
 

公告

所有文章皆为原创,若转载请标明出处,谢谢~

新浪微博,欢迎关注:

导航

2023年9月
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

统计

常用链接

留言簿(58)

随笔分类(130)

随笔档案(151)

个人收藏

最新随笔

搜索

最新评论

阅读排行榜

评论排行榜

网站地图