星星博客 »  > 

kubernetes===》智能负载均衡器service

一、智能负载均衡器service(负载均衡和自动发现)

service 是 k8s 中的一个重要概念,主要是提供负载均衡和服务自动发现。它是 k8s 中最核心的资源之一,每一个 Service 就是我们平常所说的一个“微服务”。在非 k8s 世界中,管理员可以通过在配置文件中指定 IP地址或主机名,容许客户端访问,但在 k8s 中这种方式是行不通的。因为 Pod 是有生命周期的,它们可以被创建或销毁。虽然通过控制器能够动态地创建 Pod,但当 Pod 被分配到某个节点时,K8s 都会为其分配一个 IP 地址,而该 IP 地址不总是稳定可依赖的。因此,在 Kubernetes 集群中,如果一组 Pod(称为 backend)为其它 Pod (称为 frontend)提供服务,那么那些 frontend 该如何发现,并连接到这组 backend 的 Pod 呢?
在这里插入图片描述
如上图所示,Kubernetes 的 Service 定义了一个服务的访问入口,前端的应用(Pod)通过这个入口地址访问其背后的一组由 Pod 副本组成的集群实例,Service 与其后端的 Pod 副本集群之间是通过 Label Selector 来实现关联的,而 Deployment 则是保证 Service 的服务能力和服务质量始终处于预期的标准。通过分析,识别并建模系统中的所有服务为微服务,最终我们的系统是由多个提供不同业务能力而彼此独立的微服务单元所组成,服务之间通过 TCP/IP 进行通信,从而形成了强大而又灵活的弹性网络,拥有强大的分布式能力、弹性扩展能力、容错能力。

1.定义service

#通过标签关联pod  通过端口暴露服务外界访问
[root@k8s-master1 ~]# vim service.ymal
apiVersion: v1
kind: Service
metadata:
  name: service
spec:
  selector:
    release: stable
  ports:
    - name: http
      port: 80
      targetPort: 80
      protocol: "TCP"
    - name: https
      port: 443
      targetPort: 443
      protocol: "TCP"

#创建
[root@k8s-master1 ~]# kubectl apply -f service.ymal 


#查看
[root@k8s-master1 ~]# kubectl get service
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          6d7h
service      ClusterIP   10.111.48.100   <none>        80/TCP,443/TCP   112s

2.service的工作方式

在 Kubernetes 迭代过程中,给 Service 设置里三种工作方式,分别是:Userspace 方式、Iptables 以及 Ipvs,这三种方式到现在为止,官方推荐使用 IPVS, 当集群不支持 IPVS 的时候,集群会降级到 Iptables。

1)userspace

Client Pod 要访问 Server Pod 时,它先将请求发给本机内核空间中的 service 规则,由它再将请求,转给监听在指定套接字上的 kube-proxy,kube-proxy 处理完请求,并分发请求到指定 Server Pod 后,再将请求递交给内核空间中的 service,由 service 将请求转给指定的 Server Pod。由于其需要来回在用户空间和内核空间交互通信,因此效率很差。
在这里插入图片描述

2)IP tables

直接由内核中的 iptables 规则,接受 Client Pod 的请求,并处理完成后,直接转发给指定 ServerPod。这种方式不再将请求转发给 kube-proxy,性能提升很多
在这里插入图片描述

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。

3.service类型

Service 是 Kubernetes 对外访问的窗口,针对不同的场景,kubernetes 为我们设置了四种 Service 的类型

1)cluster IP(向集群内部暴露一个IP)

#kubernetes 默认就是这种方式,是集群内部访问的方式,外部是无法访问的。
其主要用于为集群内 Pod 访问时,提供的固定访问地址,默认是自动分配地址,可使用 ClusterIP 关键字指定固定 IP。

#1.查看ClusterIP模式下IP
[root@k8s-master1 ~]# kubectl get service
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          6d7h
service      ClusterIP   10.111.48.100   <none>        80/TCP,443/TCP   112s

#2.内部访问
[root@k8s-master1 ~]# curl 10.111.48.100
<!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>

2)NodePort(因需维护多个端口,企业里不常用,可用于测试负载均衡)

#NodePort 是将主机 IP 和端口跟 kubernetes 集群所需要暴露的 IP 和端口进行关联,方便其对外提供服务。
内部可以通过 ClusterIP 进行访问,外部用户可以通过 NodeIP:NodePort 的方式单独访问每个 Node 上的实例

#1.查看模式
[root@k8s-master1 ~]# kubectl get service
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          6d7h
service      ClusterIP   10.111.48.100   <none>        80/TCP,443/TCP   112s


#2.修改service的类型为NodePort
[root@k8s-master1 ~]# kubectl edit service service 
spec:
  clusterIP: 10.111.48.100
  clusterIPs:
  - 10.111.48.100
  externalTrafficPolicy: Cluster
  ports:
  - name: http
    nodePort: 30681
    port: 80
    protocol: TCP
    targetPort: 80
  - name: https
    nodePort: 32544
    port: 443
    protocol: TCP
    targetPort: 443
  selector:
    release: stable
  sessionAffinity: None
  type: NodePort  #修改类型
status:
  loadBalancer: {}

#3.查看修改后的类型
[root@k8s-master1 ~]# kubectl get service
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP                      6d8h
service      NodePort    10.111.48.100   <none>        80:30681/TCP,443:32544/TCP   52m

#4.通过30681端口外网访问(如下图)

在这里插入图片描述

3)LoadBalancer

#LoadBalancer 是实现暴露服务的另一种解决方案,它依赖于公有云弹性IP实现。
负载均衡器是异步创建的,关于被提供的负载均衡器的信息将会通过 Service 的 status.loadBalancer 字段被发布出去。

#测试需要公网弹性IP模板

4)ExternalName

#ExternalName Service 是 Service 的一个特例,它没有选择器,也没有定义任何端口或 Endpoints。
它的作用是返回集群外 Service 的外部别名。
它将外部地址经过集群内部的再一次封装(实际上就是集群 DNS 服务器将CNAME 解析到了外部地址上),实现了集群内部访问即可。
例如你们公司的镜像仓库,最开始是用 ip 访问,等到后面域名下来了再使用域名访问。你不可能去修改每处的引用。但是可以创建一个 ExternalName,首先指向到 ip,等后面再指向到域名。

5)Headless Service

#headless serivces字面意思无 service 其实就是改 service
对外无提供 IP。一般用于对外提供域名服务

相关文章