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==可自定义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,等后面再指向到域名。

apiVersion: v1
kind: Service
metadata:
  name: baidu  #定义的别名
spec:
  externalName: www.baidu.com  #给谁定义别名
  type: ExternalName

#注:给www.baidu.com定义一个别名baidu
就可以通过baidu.default.svc.cluter.local访问www.baidu.com 
以后如果想访问别的可直接修改externalName(做到无感知迁移)
#实例:
#1.创建externalname.ymal
[root@k8s-master1 ~]# vim extername.ymal
apiVersion: v1
kind: Service
metadata:
  name: baidu  #定义的别名
spec:
  externalName: www.baidu.com  #给谁定义别名
  type: ExternalName


#2.创建externalname类型的service
[root@k8s-master1 ~]# kubectl apply -f extername.ymal 
service/baidu created

#3.查看service
[root@k8s-master1 ~]# kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE
baidu        ExternalName   <none>          www.baidu.com   <none>                       32m
kubernetes   ClusterIP      10.96.0.1       <none>          443/TCP                      6d10h
service      NodePort       10.111.48.100   <none>          80:30681/TCP,443:32544/TCP   179m

#4.查看域名解析的IP
[root@k8s-master1 ~]# kubectl run test1 -it --rm --image=busybox:1.28.3
If you don't see a command prompt, try pressing enter.
/ # nslookup baidu
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      baidu
Address 1: 112.80.248.75
Address 2: 112.80.248.76
#注:可以在外网访问112.80.248.75或者112.80.248.76可得到百度搜索窗口(如下图)

#5.修改域名
[root@k8s-master1 ~]# vim extername.ymal 
apiVersion: v1
kind: Service
metadata:
  name: baidu
spec:
  externalName: www.aliyun.com  #给aliyun换成baidu别名
  type: ExternalName


#6.查看service
[root@k8s-master1 ~]# kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
baidu        ExternalName   <none>          www.aliyun.com    <none>                       58m
kubernetes   ClusterIP      10.96.0.1       <none>        443/TCP                      6d10h
service      NodePort       10.111.48.100   <none>        80:30681/TCP,443:32544/TCP   3h26m


#7.查看域名解析
[root@k8s-master1 ~]# kubectl run test1 -it --rm --image=busybox:1.28.3
If you don't see a command prompt, try pressing enter.
/ # nslookup baidu
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      baidu
Address 1: 2401:b180:1:50::f
Address 2: 2401:b180:1:60::6
Address 3: 106.11.248.144
#注:此时可以在外网访问106.11.248.144可访问到淘宝(如下图)

#8.在集群内部访问
[root@k8s-master1 ~]# kubectl exec -it deployment-5849786498-4s9rf  -- bash
root@deployment-5849786498-4s9rf:/# curl baidu.default.svc.cluster.local  #第一种方法
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr/>Powered by Tengine<hr><center>tengine</center>
</body>
</html>
root@deployment-5849786498-4s9rf:/# curl baidu  #第二种方法
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr/>Powered by Tengine<hr><center>tengine</center>
</body>
</html>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5)Headless Service(仅仅需要关联pod的场景中可以使用此类型)
#headless serivces字面意思无 service 其实就是改 service
对外无提供 IP。一般用于对外提供域名服务

#1.创建headless.yaml
[root@k8s-master1 ~]# vim headless.yaml 
apiVersion: v1
kind: Service
metadata:
  name: headless-svc
spec:
  clusterIP: None 
  selector:
    app: wordpress
  ports:
    - name: https
      port: 80
      targetPort: 80

#2.创建headless的service
[root@k8s-master1 ~]# kubectl apply -f headless.yaml 

#3.查看headless
[root@k8s-master1 ~]# kubectl get svc  #没有集群IP称为无头service
NAME           TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)   AGE
baidu          ExternalName   <none>          www.aliyun.com   <none>    26h
headless-svc   ClusterIP      None            <none>           80/TCP    8h  
kubernetes     ClusterIP      10.96.0.1       <none>           443/TCP   7d12h
service        ClusterIP      10.109.114.72   <none>           80/TCP    6h44m

4.service与Pod之间的关系

#service通过endpoints连接pod
endpoints与service是同步创建同步删除的资源类型

#1.查看资源详细信息
[root@k8s-master1 ~]# kubectl describe service service 
Name:              service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          release=stable
Type:              ClusterIP
IP Families:       <none>
IP:                10.109.114.72
IPs:               10.109.114.72
Port:              http  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.10:80,10.244.1.11:80,10.244.1.2:80 + 3 more...   #分配podIP
Session Affinity:  None
Events:            <none>


#2.查看所有endpoints
[root@k8s-master1 ~]# kubectl get endpoints
NAME           ENDPOINTS                                                 AGE
headless-svc   <none>                                                    9h
kubernetes     192.168.12.11:6443                                        7d12h
service        10.244.1.10:80,10.244.1.11:80,10.244.1.2:80 + 3 more...   7h2m


#3.查看endpoint资源详细信息
[root@k8s-master1 ~]# kubectl describe endpoints service 
Name:         service
Namespace:    default
Labels:       <none>
Annotations:  endpoints.kubernetes.io/last-change-trigger-time: 2021-04-02T03:03:55Z
Subsets:
  Addresses:          10.244.1.10,10.244.1.11,10.244.1.2,10.244.2.16,10.244.2.17,10.244.2.19  #可用IP
  NotReadyAddresses:  <none>  #无效IP
  Ports:
    Name  Port  Protocol
    ----  ----  --------
    http  80    TCP

Events:  <none>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值