kubernetes-Service控制器

Service存在的意义

Service引入主要是解决Pod的动态变化,提供统一访问入口:

  • 防止Pod失联,准备找到提供同一个服务的Pod(服务发现)
  • 定义一组Pod的访问策略(负载均衡)

Pod与Service的关系

Service为Pod提供统一的访问入口,和负载均衡,使得应用和应用之间可以访问

  • Service通过标签关联一组Pod
  • Service为一组Pod提供负载均衡能力
    在这里插入图片描述

Service定义与创建

# 创建Service
kubectl expose
kubectl create service
# 查看所有pod的标签
kubectl get pods -A --show-labels
# 查看指定标签的Pod
kubectl get pods -A -l app=web

service基本配置解析

在这里插入图片描述
外部访问就访问集群中任意节点IP+30805即可,内部访问可以使用10.96.93.68:80这个来访问
在这里插入图片描述

多端口的定义

如果一个Pod中有两个端口需要暴露,那么需要通过名称进行区分

apiVersion: v1
kind: Service
metadata:
  labels:
    app: web
  name: web
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  - name: https
    port: 443
    protocol: TCP
    targetPort: 443
  selector:
    app: web
  type: NodePort

Service三种类型

类型描述
ClusterIP集群内部使用(Pod)
NodePort对外暴露应用(浏览器)
LoadBalancer对外暴露应用,适合公有云

ClusterIP

clusterIP是默认的,分配一个稳定的IP地址,即VIP,只能在集群内部访问

# 示例
spec:
  type: ClusterIP
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: web

NodePort

在每个节点上启用一个端口来暴露服务,可以在集群外部访问,也会分配一个稳定内部集群IP地址
访问地址: <任意NodeIP>:<NodePort>
默认NodePort端口范围:30000-32767

# 示例
spec:
  type: NodePort
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
    # 指定端口
    nodePort: 30007
  selector:
    app: web

NodePort会在每台Node上监听端口接收用户流量,在实际情况下,对用户暴露的只会有一个IP和端口,那么那么多台Node该使用那台让用户访问呢?
这时就需要在前面加入一个公网负载均衡器为项目提供统一访问入口了,所以引入了LoadBalancer类型

LoadBalancer

与NodePort类似,在每个节点上启用一个端口来暴露服务,除此之外,Kubernetes会请求底层云平台(如阿里云、腾讯云、AWS等)上的负载均衡器,将每个Node([NodeIP]:[NodePort])作为后端添加进去

Service代理模式

service如何实现的负载均衡
service的底层实现主要有iptables和ipvs二种网络模式,决定了如何转发流量

iptables

在这里插入图片描述
在client通过页面去请求某个IP时,iptables会把这些请求转发到对应的pod上(在此过程中他实现了负载均衡)
而这个有是通过kubernetes中的kube-proxy来做管理的,他会从apiserver中获取到创建的service,并生成相关的负载均衡器规则

iptables如何实现负载均衡器

这个是目前的service
在这里插入图片描述

# 使用iptables查看下该service的规则
[root@k8s-master ~]# iptables-save | grep web
# 查询出来的规则其实在k8s中只有两种访问方式
# 1、集群内部应用间访问
# 该规则链意思为:在该机器中访问10.96.93.68和80端口,就会被"KUBE-SVC-LOLE4ISW44XBNF3G"链匹配到
-A KUBE-SERVICES -d 10.96.93.68/32 -p tcp -m comment --comment "default/web cluster IP" -m tcp --dport 80 -j KUBE-SVC-LOLE4ISW44XBNF3G
# 2、集群外部访问
# 该链的意思是该规则在"KUBE-NODEPORTS"中,重定向到了"KUBE-SVC-LOLE4ISW44XBNF3G"
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/web" -m tcp --dport 30805 -j KUBE-SVC-LOLE4ISW44XBNF3G

通过上面的筛查,可以找到service中对应name所对应的规则链,这些规则链又链到了别的名称下,继续筛查

# 过滤出之前两条链重定向的链
[root@k8s-master ~]# iptables-save | grep KUBE-SVC-LOLE4ISW44XBNF3G
# 可以看到以下三个链,因为有三个pod,所以有三个链,几个pod几个规则,他们就是用来实现负载均衡
# 主要是运用了"--mode random --probability 0.33333333349",他们两个前面的代表随机,后面的代表概率
# 先去匹配第一条所有的规则为30%,如果没有匹配到就去匹配第二条,那么剩下的规则为50%,如果还没有满足,那么最后一条就是100%的匹配率(我这里只是粗略的描述一下,帮忙理解下他的概率为什么不一样)
-A KUBE-SVC-LOLE4ISW44XBNF3G -m comment --comment "default/web" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-TMXBUDFDUGA527AY
-A KUBE-SVC-LOLE4ISW44XBNF3G -m comment --comment "default/web" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-G5VJ3MBTAO2VUPVQ
-A KUBE-SVC-LOLE4ISW44XBNF3G -m comment --comment "default/web" -j KUBE-SEP-C6PMY4SMHY542QDH

ok,那么我们找到了负载均衡的主题,接下来筛选最后一步" KUBE-SEP-G5VJ3MBTAO2VUPVQ"

# 这是就可以看到他会转发到对应pod上去了
# 三条规则分别对应三个pod
[root@k8s-master ~]# iptables-save | grep  KUBE-SEP-TMXBUDFDUGA527AY
-A KUBE-SEP-TMXBUDFDUGA527AY -p tcp -m comment --comment "default/web" -m tcp -j DNAT --to-destination 10.244.36.75:80
-----------------------------------------------------------------------------------------------
[root@k8s-master ~]# iptables-save | grep  KUBE-SEP-G5VJ3MBTAO2VUPVQ
-A KUBE-SEP-G5VJ3MBTAO2VUPVQ -p tcp -m comment --comment "default/web" -m tcp -j DNAT --to-destination 10.244.36.76:80
-----------------------------------------------------------------------------------------------
[root@k8s-master ~]# iptables-save | grep KUBE-SEP-C6PMY4SMHY542QDH
-A KUBE-SEP-C6PMY4SMHY542QDH -p tcp -m comment --comment "default/web" -m tcp -j DNAT --to-destination 10.244.36.77:80

上诉信息可以看到pod的转发(使用的是DNAT转发)情况,那么我们来看看转发到的对应IP是不是Pod的IP

[root@k8s-master ~]# kubectl get pods -o wide
NAME                   READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
web-586db47859-5vqr4   1/1     Running   0          16h   10.244.36.76   k8s-node1   <none>           <none>
web-586db47859-ljvm4   1/1     Running   0          16h   10.244.36.75   k8s-node1   <none>           <none>
web-586db47859-tkp2k   1/1     Running   0          16h   10.244.36.77   k8s-node1   <none>           <none>

上诉可以看到他一共走了3步,一地步就是定义了service的规则,第二步就是负载均衡,进行转发,第三步就是将流量转发到不通的pod,为什么会增加第二步,就是因为需要实现流量可以均衡的分布

ipvs

在这里插入图片描述
ipvs是内核中的一块
和iptables类似,在客户端请求网页或接口时,ipvs规则会转发对应pod上
ipvs有两个概念,一个是虚拟服务器(Virtual Server)、一个是真实服务器(Real Server)

将kube-proxy的模式修改为ipvs模式
# 现在各个节点安装ipvs的查看工具,方便后续查看规则
[root@k8s-master ~]# yum -y install ipvsadm
kubeadm方式修改ipvs模式

他默认情况下就是iptables
可以在log日志中看到该内容

[root@k8s-master ~]# kubectl logs  kube-proxy-7nxhg -n kube-system
# 该行表示没有指定proxy,所以默认使用iptables
W0217 01:22:42.848296       1 server_others.go:592] Unknown proxy mode "", assuming iptables proxy
# kube-proxy配置文件以configmap方式存储

[root@k8s-master ~]# kubectl edit configmap kube-proxy -n kube-system
...
  mode: "ipvs"
...
# 如果想让所有节点生效,那么需要重建所有节点的kube-proxy Pod
[root@k8s-master ~]# kubectl delete pod kube-proxy-7nxhg -n kube-system
# 重建后查看日志可以看到如下这行
[root@k8s-master ~]# kubectl logs  kube-proxy-7nb54 -n kube-system
I0225 04:11:49.456997       1 server_others.go:276] creating dualStackProxier for ipvs
# 在没有重建之前ipvs是没有规则的
[root@k8s-master ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
# ipvs的规则看着是比iptables更直观的
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.17.0.1:30805 rr
  -> 10.244.36.75:80              Masq    1      0          0         
  -> 10.244.36.76:80              Masq    1      0          0         
  -> 10.244.36.77:80              Masq    1      0          0         
TCP  10.96.0.1:443 rr
  -> 192.168.113.148:6443         Masq    1      0          0         
TCP  10.96.0.10:53 rr
  -> 10.244.235.193:53            Masq    1      0          0         
  -> 10.244.235.194:53            Masq    1      0          0         
TCP  10.96.0.10:9153 rr
  -> 10.244.235.193:9153          Masq    1      0          0         
  -> 10.244.235.194:9153          Masq    1      0          0         
TCP  10.96.93.68:80 rr
  -> 10.244.36.75:80              Masq    1      0          0         
  -> 10.244.36.76:80              Masq    1      0          0         
  -> 10.244.36.77:80              Masq    1      0          0         
TCP  10.244.235.192:30805 rr
  -> 10.244.36.75:80              Masq    1      0          0         
  -> 10.244.36.76:80              Masq    1      0          0         
  -> 10.244.36.77:80              Masq    1      0          0         
TCP  127.0.0.1:30805 rr
  -> 10.244.36.75:80              Masq    1      0          0         
  -> 10.244.36.76:80              Masq    1      0          0         
  -> 10.244.36.77:80              Masq    1      0          0         
TCP  192.168.113.148:30805 rr
  -> 10.244.36.75:80              Masq    1      0          0         
  -> 10.244.36.76:80              Masq    1      0          0         
  -> 10.244.36.77:80              Masq    1      0          0         
UDP  10.96.0.10:53 rr
  -> 10.244.235.193:53            Masq    1      0          0         
  -> 10.244.235.194:53            Masq    1      0          0  
二进制方式修改ipvs模式
# 配置文件路径根据实际安装目录为准
[root@k8s-master ~]# vim kube-proxy-config.yaml
mode: ipvs
ipvs:
  scheduler: "rr"
[root@k8s-master ~]# systemctl restart kube-proxy 
iptables VS ipvs

iptables

  • 灵活、功能强大
  • 规则便利匹配和更新,呈线性延时

ipvs

  • 工作在内核态,有更好的性能
  • 调度算法丰富:rr,wrr,lc,wlc,ip hash…

建议使用ipvs

Service DNS名称

CoreDNS:是一个DNS服务器,Kubernetes默认采用,以Pod部署在集群中
CoreDNS服务监视Kubernetes API,为每一个Service创建DNS记录用于域名解析

ClusterIP A记录格式: <service-name>.<namespace-name>.svc.cluster.local
示例:my-svc.my-namespace.svc.cluster.local

案例
# 查看集群中DNS的IP地址
[root@k8s-master ~]# kubectl get svc  -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   8d

# 创建一个busyboxpod
[root@k8s-master ~]# kubectl run bs --image=busybox:1.28.4 -- sleep 24h
pod/bs created
[root@k8s-master ~]# kubectl get pod
NAME                   READY   STATUS    RESTARTS   AGE
bs                     1/1     Running   0          9s
[root@k8s-master ~]# kubectl exec -it bs sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # cat /etc/resolv.conf 
# 查看他的DNS地址就是集群中CoreDNS的IP
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local localdomain
options ndots:5
# 之前是有创建一个名为web的service,我们试着去解析一下
# 可以看到是被解析成功了
/ # nslookup web
# DNS地址,"kube-dns.kube-system.svc.cluster.local",域名全名,如果在其他业务需要使用的话,劲量去使用这个全名
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
# "web.default.svc.cluster.local" web的域名全名,也可以做解析,也可以直接ping
# 其所对应的IP地址为10.96.93.68
Name:      web
Address 1: 10.96.93.68 web.default.svc.cluster.local
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值