学习kubernetes(四):学习service的工作机制
2020-04-01 本文已影响0人
ljyfree
主要参考:https://github.com/jasonGeng88/blog/blob/master/201707/k8s-service.md
service是一个抽象概念,定义了一个服务的多个pod逻辑合集和访问pod的策略,一般把service称为微服务
service可以认为是在pod之上抽象出来的,可以固定被访问的IP,可以实现负载均衡
环境搭建
- 利用现有的k8s集群
- 使用镜像jasonn/php-echoserver,通过deployment来创建2个pod
[root@k8s-master ~]# vim deploy-echoserver.yml
apiVersion: apps/v1
kind: Deployment
metadata:
# Deployment 实例名称
name: echoserver
spec:
# 设置 Pod 个数
replicas: 2
selector:
matchLabels:
app: echoserver
template:
metadata:
# 设置 Pod 标签
labels:
app: echoserver
spec:
# 运行 docker 镜像
containers:
- name: echoserver
image: jasonn/php-echoserver
imagePullPolicy: IfNotPresent
[root@k8s-master ~]# kubectl create -f deploy-echoserver.yml
deployment.apps/echoserver created
[root@k8s-master ~]#
- echoserver的作用就是获取自己的IP,并写入index.html
[root@k8s-master ~]# kubectl exec -it echoserver-64fc9848f8-5djnq bash
root@echoserver-64fc9848f8-5djnq:/var/www/html#
root@echoserver-64fc9848f8-5djnq:/var/www/html# cat index.php
<?php
echo exec('/bin/hostname -i');
root@echoserver-64fc9848f8-5djnq:/var/www/html# /bin/hostname -i
172.20.140.69
root@echoserver-64fc9848f8-5djnq:/var/www/html#
- 创建service,将pod的80端口映射到service的8080端口
[root@k8s-master ~]# cat service-echoserver.yml
apiVersion: v1
kind: Service
metadata:
# Service 实例名称
name: svc-echoserver
spec:
ports:
- protocol: TCP
# Service 端口地址
port: 8080
# Pod 端口地址
targetPort: 80
selector:
# 匹配符合标签条件的 Pod
app: echoserver
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl create -f service-echoserver.yml
service/svc-echoserver created
[root@k8s-master ~]#
- 使用镜像centos启动pod,通过curl访问service
[root@k8s-master ~]# cat deploy-centos.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-centos
spec:
replicas: 3
selector:
matchLabels:
app: centos
template:
metadata:
labels:
app: centos
spec:
containers:
- name: app-centos
image: centos
imagePullPolicy: IfNotPresent
command: ["top", "-b"]
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl create -f deploy-centos.yaml
deployment.apps/deploy-centos created
[root@k8s-master ~]#
- 此时pod/deployment/service的信息
[root@k8s-master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deploy-centos-6d96869bfd-jw7hg 1/1 Running 0 14m 172.20.140.72 192.168.122.198 <none> <none>
deploy-centos-6d96869bfd-vrfgk 1/1 Running 0 14m 172.20.235.200 192.168.122.135 <none> <none>
deploy-centos-6d96869bfd-zzqvg 1/1 Running 0 14m 172.20.109.70 192.168.122.143 <none> <none>
echoserver-64fc9848f8-5djnq 1/1 Running 0 138m 172.20.140.69 192.168.122.198 <none> <none>
echoserver-64fc9848f8-q4dtq 1/1 Running 0 138m 172.20.235.196 192.168.122.135 <none> <none>
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
deploy-centos 3/3 3 3 14m
echoserver 2/2 2 2 138m
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.68.0.1 <none> 443/TCP 20h
svc-echoserver ClusterIP 10.68.119.29 <none> 8080/TCP 141m
[root@k8s-master ~]#
- Endpoint随Service一起生成,暴露的就是pod的地址加端口
[root@k8s-master ~]# kubectl get ep
NAME ENDPOINTS AGE
kubernetes 192.168.122.135:6443 20h
svc-echoserver 172.20.140.69:80,172.20.235.196:80 146m
[root@k8s-master ~]#
验证
- 通过centos容器多次访问svc-echoserver的IP:8080,可以发现服务是由两个echoserver轮流提供
[root@k8s-master ~]# kubectl exec -it deploy-centos-6d96869bfd-zzqvg curl 10.68.119.29:8080
172.20.140.69[root@k8s-master ~]#
[root@k8s-master ~]# kubectl exec -it deploy-centos-6d96869bfd-zzqvg curl 10.68.119.29:8080
172.20.235.196[root@k8s-master ~]#
[root@k8s-master ~]# kubectl exec -it deploy-centos-6d96869bfd-zzqvg curl 10.68.119.29:8080
172.20.140.69[root@k8s-master ~]#
[root@k8s-master ~]# kubectl exec -it deploy-centos-6d96869bfd-zzqvg curl 10.68.119.29:8080
172.20.235.196[root@k8s-master ~]#
[root@k8s-master ~]#
分析
- 笔者的k8s版本是v1.17.2,已经安装了ipvs
- ipvs运行在主机上,在真实pod集群前充当负载均衡器。ipvs可以将基于TCP和UDP的服务请求转发到真实的pod上,并使真实pod的服务在单个IP 地址上显示为虚拟服务。
[root@k8s-master ~]# ip addr
...
5: kube-ipvs0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default
link/ether ce:32:81:bd:cc:d2 brd ff:ff:ff:ff:ff:ff
inet 10.68.173.81/32 brd 10.68.173.81 scope global kube-ipvs0
valid_lft forever preferred_lft forever
inet 10.68.142.144/32 brd 10.68.142.144 scope global kube-ipvs0
valid_lft forever preferred_lft forever
inet 10.68.0.2/32 brd 10.68.0.2 scope global kube-ipvs0
valid_lft forever preferred_lft forever
inet 10.68.172.108/32 brd 10.68.172.108 scope global kube-ipvs0
valid_lft forever preferred_lft forever
inet 10.68.0.1/32 brd 10.68.0.1 scope global kube-ipvs0
valid_lft forever preferred_lft forever
inet 10.68.119.29/32 brd 10.68.119.29 scope global kube-ipvs0 ##添加echoserver service后自动添加该虚拟端口
valid_lft forever preferred_lft forever
inet 10.68.145.230/32 brd 10.68.145.230 scope global kube-ipvs0
valid_lft forever preferred_lft forever
- 然后根据round-robin算法分配到真实的pod的上
[root@k8s-master ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
...
TCP 10.68.119.29:8080 rr
-> 172.20.140.75:80 Masq 1 0 0
-> 172.20.235.202:80 Masq 1 0 0