Service(对外暴露你的应用)
Service是什么与Service存在的意义
Service引入主要是解决Pod的动态变化,提供统一访问入口:
-
防止Pod失联,准备找到提供同一个服务的Pod(服务发现)
-
定义一组Pod的访问策略(负载均衡)
Pod与Service的关系
-
Service通过标签关联一组Pod
-
Service使用iptables或者ipvs为一组Pod提供负载均衡能力
Service定义与创建
vim service.yaml
apiVersion: v1 |
#创建service: |
Service三种类型
-
ClusterIP:集群内部使用
-
NodePort:对外暴露应用(集群外)
-
LoadBalancer:对外暴露应用,适用公有云
ClusterIP:默认,分配一个稳定的IP地址,即VIP,只能在集群内部访问。
vim service.yaml
apiVersion: v1 |
访问
kubectl apply -f service.yaml |
NodePort:在每个节点上启用一个端口来暴露服务,可以在集群 外部访问。也会分配一个稳定内部集群IP地址。 访问地址:<任意NodeIP>: 端口范围:30000-32767
vim service-node.yaml
apiVersion: v1 |
访问
kubectl apply -f service-node.yaml |
NodePort:会在每台Node上监听端口接收用户流量,在实际情 况下,对用户暴露的只会有一个IP和端口,那这么多台Node该使 用哪台让用户访问呢?
这时就需要前面加一个公网负载均衡器为项目提供统一访问入口了。
负载均衡器:
-
开源:nginx、lvs、haproxy
-
公有云:SLB
upstream demo { |
LoadBalancer:与NodePort类似,在每个节点上启用一个端口来暴 露服务。除此之外,Kubernetes会请求底层云平台(例如阿里云、腾 讯云、AWS等)上的负载均衡器,将每个Node ([NodeIP]:[NodePort])作为后端添加进去。
Service代理模式
Service的底层实现主要有iptables和ipvs二种网络模式,决定了如何转发流量
基于iptables实现负载均衡的一个过程
1、在浏览器访问 http://192.168.0.11:30009/
2.数据包经过iptables规则匹配,重定向到另一个链KUBE-SVC-LOLE4ISW44XBNF3G
-A KUBE-NODEPORTS -p tcp -m comment --comment “default/web” -m tcp --dport 30009 -j KUBE-SVC-LOLE4ISW44XBNF3G
3.一组规则,有几个pod就会创建几条规则,这里实现了负载均衡 (概率1/3,1/2,1)
-A KUBE-SVC-LOLE4ISW44XBNF3G -m comment --comment “default/web” -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-PXRBKXV7I65SLLDB
-A KUBE-SVC-LOLE4ISW44XBNF3G -m comment --comment “default/web” -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-4MXWCRSI3HRHILKZ
-A KUBE-SVC-LOLE4ISW44XBNF3G -m comment --comment “default/web” -j KUBE-SEP-ODUGDMBPYLOH457E
4.使用DNAT转发到具体的pod
-A KUBE-SEP-PXRBKXV7I65SLLDB -p tcp -m comment --comment “default/web” -m tcp -j DNAT --to-destination 10.244.169.133:80
-A KUBE-SEP-4MXWCRSI3HRHILKZ -p tcp -m comment --comment “default/web” -m tcp -j DNAT --to-destination 10.244.36.67:80
-A KUBE-SEP-ODUGDMBPYLOH457E -p tcp -m comment --comment “default/web” -m tcp -j DNAT --to-destination 10.244.36.68:80
针对ClusterIP实现的转发,后面与nodeport一样,回到了上面的第三步
-A KUBE-SERVICES -d 10.109.90.58/32 -p tcp -m comment --comment “default/web cluster IP” -m tcp --dport 80 -j KUBE-SVC-LOLE4ISW44XBNF3G
kubeadm方式修改ipvs模式:
kubectl edit configmaps kube-proxy -n kube-system |
注: 1、kube-proxy配置文件以configmap方式存储 2、如果让所有节点生效,需要重建所有节点kube-proxy pod
在node1节点上安装ipvsadm工具
yum -y install ipvsadm |
ip a
二进制方式修改ipvs模式:
vi kube-proxy-config.yml
mode: ipvs
ipvs:
scheduler: "rr“
systemctl restart kube-proxy
注:参考不同资料,文件名可能不同
流程包流程:客户端 ->NodePort/ClusterIP(iptables/Ipvs负载均衡规则) -> 分布在各节点Pod
查看负载均衡规则:
- iptables模式
iptables-save |grep |
- ipvs模式
ipvsadm -L -n |
当一个客户端访问service的时候,经过iptables/ipvs进行负载均衡,负载到后端的pod上,iptables/ipvs的规则是由kube-proxy去创建的。
当出现问题的时候,应该先检查的service的配置的是不是对的(标签端口等等),再检查kube-proxy是不是正常的,有没有创建对应的iptables/ipvs规则。
Service DNS名称
CoreDNS:是一个DNS服务器,Kubernetes默认采用,以Pod部署在集群中,CoreDNS服 务监视Kubernetes API,为每一个Service创建DNS记录用于域名解析。
CoreDNS YAML文件:
https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns/coredns
ClusterIP A记录格式:
示例:my-svc.my-namespace.svc.cluster.local
当我们在pod内做nslookup(dns)解析时,它会请求coredns pod,coredns里面存放了从k8smaster中获取的service对应的dns记录,就会帮你解析成对应service的IP。
Iptables VS IPVS
Iptables:
-
灵活,功能强大
-
规则遍历匹配和更新,呈线性时延
IPVS:
-
工作在内核态,有更好的性能
-
调度算法丰富:rr,wrr,lc,wlc,ip hash…
生产环境建议使用IPVS
1、创建一个deployment 副本数 3,然后滚动更新镜像版本,并记录这个更新记录,最后再回滚到上一个版本
vim web-deployment.yaml
apiVersion: apps/v1 |
kubectl apply -f web-deployment.yaml |
2、给一个应用扩容副本数为3
kubectl scale deployment web-deployment --replicas=6 |
3、创建一个pod,其中运行着nginx、redis、memcached 3个容器
vim nginx-redis-memcached.yaml
apiVersion: apps/v1 |
验证查看
kubectl apply -f nginx-redis-memcached.yaml |
4、给一个pod创建service,并可以通过ClusterIP/NodePort访问
vim service-node.yaml
apiVersion: v1 |
验证查看
kubectl apply -f service-node.yaml |
5、创建deployment和service,使用busybox容器nslookup解析service
kubectl run -it dns-test --image=busybox -- sh |
注:自由发挥,实现需求即可