service详解
service(智能负载均衡器)service主要是提供负载均衡和服务自动发现。它是 k8s 中最核心的资源之一, 每一个 Service 就是我们平常所说的一个“微服务”。如上图所示,Kubernetes 的 Service 定义了一个服务的访问入口,前端的应用(Pod)通过这个入口地址访 问其背后的一组由 Pod 副本组成的集群实例,Service 与其后端的 Pod 副本集群之间是通过 La
一、service(智能负载均衡器)
service主要是提供负载均衡和服务自动发现。它是 k8s 中最核心的资源之一, 每一个 Service 就是我们平常所说的一个“微服务”。命名空间级资源
如上图所示,Kubernetes 的 Service 定义了一个服务的访问入口,前端的应用(Pod)通过这个入口地址访 问其背后的一组由 Pod 副本组成的集群实例,Service 与其后端的 Pod 副本集群之间是通过 Label 来 实现关联的,而 Deployment 则是保证 Service 的服务能力和服务质量始终处于预期的标准。
通过分析,识别并建模系统中的所有服务为微服务,最终我们的系统是由多个提供不同业务能力而彼此独立 的微服务单元所组成,服务之间通过 TCP/IP 进行通信,从而形成了强大而又灵活的弹性网络,拥有强大的分布 式能力、弹性扩展能力、容错能力。
vim service.yaml
apiVersion: v1
kind: Service
metadata:
name: service
spec:
selector:
release: stable
ports:
- name: http
#负载均衡端口
port: 80
#容器内端口
targetPort: 80
#网络代理的类型默认tcp
protocol: "TCP"
- name: https
port: 443
targetPort: 443
protocol: "TCP"
二、service的工作方式
在 Kubernetes 迭代过程中,给 Service 设置里三种工作方式,分别是:Userspace 方式、Iptables 以及 Ipvs, 这三种方式到现在为止,官方推荐使用 IPVS, 当集群不支持 IPVS 的时候,集群会降级到 Iptables。
2.1.userspace
Client Pod 要访问 Server Pod 时,它先将请求发给本机内核空间中的 service 规则,由它再将请求,转给监听 在指定套接字上的 kube-proxy,kube-proxy 处理完请求,并分发请求到指定 Server Pod 后,再将请求递交给内 核空间中的 service,由 service 将请求转给指定的 Server Pod。由于其需要来回在用户空间和内核空间交互通信, 因此效率很差
2.2.Iptables 模型 (软件转发)
直接由内核中的 iptables 规则,接受 Client Pod 的请求,并处理完成后,直接转发给指定 ServerPod。这 种方式不再将请求转发给 kube-proxy,性能提升很多。
2.3.Ipvs 模型 (内核转发)
在 ipvs 模式下,kube-proxy 监视 Kubernetes 服务和端点,调用 netlink 接口相应地创建 IPVS 规则, 并 定期将 IPVS 规则与 Kubernetes 服务和端点同步。 该控制循环可确保 IPVS 状态与所需状态匹配。 访问服务 时,IPVS 将流量定向到后端 Pod 之一。 IPVS 代理模式基于类似于 iptables 模式的 netfilter 挂钩函数,但是使用哈希表作为基础数据结构,并且 在内核空间中工作。 这意味着,与 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向 通信的延迟要短,并且在同步代理规则时具有更好的性能。与其他代理模式相比,IPVS 模式还支持更高的网络 流量吞吐量。
总结:kube-proxy 都通过 watch 的方式监控着 kube-APIServer 写入 etcd 中关于 Pod 的最新状态 信息,它一旦检查到一个 Pod 资源被删除了 或 新建,它将立即将这些变化,反应在 iptables 或 ipvs 规则中, 以便 iptables 和 ipvs 在调度 Clinet Pod 请求到 Server Pod 时,不会出现 Server Pod 不存在的情况。 自 k8s1.1 以后,service 默认使用 ipvs 规则,若 ipvs 没有被激活,则降级使用 iptables 规则. 但在 1.1 以前, service 使用的模式默认为 userspace。
三、service的类型
Service 是 Kubernetes 对外访问的窗口,针对不同的场景,kubernetes 为我们设置了四种 Service 的类型。
3.1.ClusterIp(向集群内部暴露一个ip)
kubernetes 默认就是这种方式,是集群内部访问的方式,外部是无法访问的。其主要用于为集群内 Pod 访 问时,提供的固定访问地址,默认是自动分配地址,可使用 ClusterIP 关键字指定固定 IP。
[root@kubernetes-master-01 test]# cat clusterip.yaml
kind: Service
apiVersion: v1
metadata:
name: my-svc
spec:
type: ClusterIP
selector:
app: nginx
ports:
- port: 80
targetPort: 80
[root@kubernetes-master-01 test]# vim clusterip.yaml
[root@kubernetes-master-01 test]# kubectl apply -f clusterip.yaml
service/my-svc created
[root@kubernetes-master-01 test]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d
my-svc ClusterIP 10.96.222.172 <none> 80/TCP 21s
nginx NodePort 10.96.6.147 <none> 80:42550/TCP 11m
[root@kubernetes-master-01 test]# curl 10.96.6.147
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body> <h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p>
<p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body
</html>
3.2.Headless Service
kubernetes 中还有一种 service 类型:headless serivces 功能,字面意思无 service 其实就是改 service 对 外无提供 IP。一般用于对外提供域名服务的时候
headless service的使用场景?
仅仅需要关联Pod的场景中可以使用此类型,即不需要提供负载均衡的情况下使用
2、Service与Pod之间的关系
service -> endpoints -> pod
endpoint与service同步创建同步删除
示例:
#编辑配置文件
[root@m01 ~]# vim headless.yaml
kind: Service
apiVersion: v1
metadata:
name: nginx-svc
spec:
clusterIP: None
selector:
app: test-svc
ports:
- port: 80
targetPort: 80
name: http
#部署
[root@m01 ~]# kubectl apply -f headless.yaml
#查看
[root@m01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
baidu ExternalName <none> www.taobao.com <none> 23h
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d
nginx-svc ClusterIP None <none> 80/TCP 9s
service ClusterIP 10.101.126.130 <none> 80/TCP,443/TCP 46h
3.3.Node Port
在宿主主机中开启一个端口与负载均衡IP的端口一一对应,外界可以使用宿主主机的端口访问集群内部服务
内部可以通过 ClusterIP 进行访问,外部用户可以通过 NodeIP:NodePort 的方式单独访问每个 Node 上的实例。
可指定端口,不指定端口则随机生成端口,默认在30000-32767之间,可通过修改/etc/kubernetes/manifests/kube-apiserver.yaml/中的
–service-node-port-range=30000-52767 指定范围在30000-52767之间
示例:
[root@kubernetes-master-01 test]# kubectl apply -f nodeport.yaml
service/my-svc created
[root@kubernetes-master-01 test]# cat nodeport.yaml
kind: Service
apiVersion: v1
metadata:
name: my-svc
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
[root@kubernetes-master-01 test]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d my-svc NodePort 10.96.159.234 <none> 80:30080/TCP 12s nginx NodePort 10.96.6.147 <none> 80:42550/TCP 17m [root@kubernetes-master-01 test]# curl 192.168.12.71:30080 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
3.4.LoadBalancer(依赖于公网ip)
是实现暴露服务的另一种解决方案,它依赖于公有云弹性IP实现
[root@kubernetes-master-01 ~]# cat > svc.yaml <<EOF apiVersion: v1
kind: Service
metadata:
name: loadbalancer
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
app: nginx
EOF
[root@kubernetes-node-01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 110d loadbalancer LoadBalancer 10.0.129.18 81.71.12.240 80:30346/TCP 11s
3.5.ExternalName
ExternalName Service 是 Service 的一个特例,它没有选择器,也没有定义任何端口或 Endpoints
将其他连接设置一个集群内部的别名,实际上就是集群 DNS 服务器将 CNAME 解析到了外部地址上,即用一个别名实现两个项目的无感知迁移
如:我们现在有两个项目,
项目一:a.abc.com 项目二:b.abc.com
用externalname将c.abc.com解析到a.abc.com,如果想将项目迁移到项目二的话,直接将c.abc.com解析到b.abc.com,此时用户就会无感知项目迁移
示例:将百度无感知迁移到淘宝上
vim externalname.yaml
apiVersion: v1
kind: Service
metadata:
name: baidu
spec:
externalName: www.baidu.com
type: ExternalName
kubectl apply -f externalname.yaml
kubectl run test -it --rm --image=busybox:1.28.3
nslookup baidu
[root@m01 ~]# vim externalname.yaml
apiVersion: v1
kind: Service
metadata:
name: baidu
spec:
externalName: www.taobao.com
type: ExternalName
kubectl apply -f externalname.yaml
kubectl run test -it --rm --image=busybox:1.28.3
nslookup baidu
四、service是如何发现pod呢?
service是通过endpoints来负载均衡pod的,endpoints是将外部的服务引入到集群里来
同一命名空间中,endpoints与service名字相同,就会关联到一起
endpoint
endpoint是k8s集群中的一个命名空间级资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址。service配置selector,endpoint controller才会自动创建对应的endpoint对象;否则,不会生成endpoint对象
endpoint作用:关联内部pod,关联外部服务
那么为什么要连接外部service呢?
是为了将外部资源变成集群内部资源,便于kubenetes管理
连接如下图:
更多推荐
所有评论(0)