文章目录

  • 一、Service介绍
  • 二、智能负载均衡器service(命名空间级资源)
  • 1.定义service
  • 2.service的工作方式
  • 1)userspace
  • 2)IP tables
  • 3)IPVS(内核转发)
  • 4)kube-proxy ipvs和iptables的异同
  • 3.service类型
  • 1)cluster IP(向集群内部暴露一个IP==可自定义IP)
  • 2)NodePort(因需维护多个端口,企业里不常用,可用于测试负载均衡,一般测试可以使用)
  • 3)LoadBalancer
  • 4)ExternalName(将其他连接设置一个集群内部的别名)
  • 实例:
  • 5)Headless Service(仅仅需要关联pod的场景中可以使用此类型)
  • 4.service与Pod之间的关系
  • headless service的使用场景?
  • 扩展
  • 1、Endpoint
  • 功能一:与service做负载均衡
  • 功能二:将外部服务引入集群
  • 2、负载分发策略
  • 3、HeadLiness类型的Service 常用
  • 创建service-headliness.yaml


一、Service介绍

kubernetes的流量负载组件:Service和Ingress

在kubernetes中,`pod是应用程序的载体`,我们可以通过pod的ip来访问应用程序,但是pod的ip地址不是固定的,这也就意味着不方便直接采用pod的ip对服务进行访问。

 为了解决这个问题,kubernetes提供了`Service`资源,`Service会对提供同一个服务的多个pod进行聚合,并且提供一个统一的入口地址`。`通过访问Service的入口地址就能访问到后面的pod服务。
`

windows server 磁盘负载均衡 service负载均衡_k8s


Service在很多情况下只是一个概念,真正起作用的其实是kube-proxy服务进程,每个Node节点上都运行着一个kube-proxy服务进程。当创建Service的时候会通过api-server向etcd写入创建的service的信息,而kube-proxy会基于监听的机制发现这种Service的变动,然后它会将最新的Service信息转换成对应的访问规则。

windows server 磁盘负载均衡 service负载均衡_TCP_02

# 10.97.97.97:80 是service提供的访问入口
# 当访问这个入口的时候,可以发现后面有三个pod的服务在等待调用,
# kube-proxy会基于rr(轮询)的策略,将请求分发到其中一个pod上去
# 这个规则会同时在集群内的所有节点上都生成,所以在任何一个节点上访问都可以。
[root@k8s-n-01 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.97.97.97:80 rr
  -> 10.244.1.39:80               Masq    1      0          0
  -> 10.244.1.40:80               Masq    1      0          0
  -> 10.244.2.33:80               Masq    1      0          0

二、智能负载均衡器service(命名空间级资源)

service 是 k8s 中的一个重要概念,主要是提供负载均衡和服务自动发现。它是 k8s 中最核心的资源之一,每一个Service 就是我们平常所说的一个“微服务”。在非 k8s 世界中,管理员可以通过在配置文件中指定 IP地址或主机名,容许客户端访问,但在 k8s 中这种方式是行不通的。因为 Pod 是有生命周期的,它们可以被创建或销毁。虽然通过控制器能够动态地创建 Pod,但当 Pod 被分配到某个节点时,K8s 都会为其分配一个 IP 地址,而该 IP 地址不总是稳定可依赖的。因此,在 Kubernetes 集群中,如果一组Pod(称为 )为其它 Pod (称为frontend )提供服务,那么那些 frontend 该如何发现,并连接到这组backend 的 Pod呢?

windows server 磁盘负载均衡 service负载均衡_k8s_03


如上图所示,KubernetesService定义了一个服务的访问入口,前端的应用(Pod通过这个入口地址访问其背后的一组由 Pod 副本组成的集群实例Service与其后端的Pod 副本集群之间是通过 Label Selector来实现关联的,而 Deployment则是保证Service的服务能力和服务质量始终处于预期的标准。通过分析,识别并建模系统中的所有服务为微服务,最终我们的系统是由多个提供不同业务能力而彼此独立微服务单元所组成,服务之间通过TCP/IP进行通信,从而形成了强大而又灵活的弹性网络,拥有强大的分布式能力、弹性扩展能力、容错能力。

1.定义service

通过标签关联pod 通过端口暴露服务外界访问

#通过标签关联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    或者 kubectl get svc 
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

windows server 磁盘负载均衡 service负载均衡_TCP_04

2.service的工作方式

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

1)userspace

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

windows server 磁盘负载均衡 service负载均衡_k8s_05

2)IP tables

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

windows server 磁盘负载均衡 service负载均衡_IP_06

3)IPVS(内核转发)

ipvs 模式下,kube-proxy 监视 Kubernetes服务和端点,调用 netlink 接口相应地创建IPVS 规则, 并定期将 IPVS 规则与 Kubernetes 服务和端点同步。 该控制循环可确保 IPVS 状态与所需状态匹配。 访问服务时,IPVS 将流量定向到后端 Pod 之一。

IPVS 代理模式基于类似于iptables 模式的 netfilter 挂钩函数,但是使用哈希表作为基础数据结构,并且在内核空间中工作。 这意味着,与 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy重定向通信的延迟要短,并且在同步代理规则时具有更好的性能。与其他代理模式相比,IPVS 模式还支持更高的网络流量吞吐量。

windows server 磁盘负载均衡 service负载均衡_IP_07

4)kube-proxy ipvs和iptables的异同

iptables与IPVS都是基于Netfilter实现的,但因为定位不同,二者有着本质的差别:iptables是为防火墙而设计的*;IPVS则专门用于高性能负载均衡,并使用更高效的数据结构(Hash表),允许几乎无限的规模扩张。

iptables相比IPVS拥有以下明显优势

  • 为大型集群提供了更好的可扩展性和性能;
  • 支持比iptables更复杂的复制均衡算法(最小负载、最少连接、加权等);
  • 支持服务器健康检查和连接重试等功能;
  • 可以动态修改ipset的集合,即使iptables的规则正在使用这个集合。

    以上不论哪种,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。

#  1、开启ipvs
[root@k8s-m-01 ~]# kubectl edit cm kube-proxy -n kube-system
    mode: "ipvs"
[root@k8s-m-01 ~]# kubectl delete pod -l k8s-app=kube-proxy -n kube-system
# 2、重新查看ipvs
[root@k8s-m-01 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.96.0.1:443 rr
  -> 192.168.15.111:6443          Masq    1      0          0         
TCP  10.96.0.10:53 rr
  -> 10.244.0.56:53               Masq    1      0          0         
  -> 10.244.0.57:53               Masq    1      0          0

3.service类型

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

kind: Service   # 资源类型
apiVersion: v1  # 资源版本
metadata: # 元数据
  name: service # 资源名称
  namespace: dev # 命名空间
spec: # 描述
  selector: # 标签选择器,用于确定当前service代理哪些pod
    app: nginx
  type: # Service类型,指定service的访问方式
  clusterIP:  # 虚拟服务的ip地址
  sessionAffinity: # session亲和性,支持ClientIP、None两个选项
  ports: # 端口信息
    - protocol: TCP 
      port: 3017  # service端口
      targetPort: 5003 # pod端口
      nodePort: 31122 # 主机端口

1)cluster IP(向集群内部暴露一个IP==可自定义IP)

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

#通过标签关联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


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 上的实例

#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端口外网访问(如下图)

windows server 磁盘负载均衡 service负载均衡_TCP_08

3)LoadBalancer

LoadBalancer是实现暴露服务的另一种解决方案,它依赖于公有云弹性IP实现

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

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

4)ExternalName(将其他连接设置一个集群内部的别名)

windows server 磁盘负载均衡 service负载均衡_Pod_09

#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>



windows server 磁盘负载均衡 service负载均衡_IP_10

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是同步创建同步删除的资源类型
headless service的使用场景?

仅仅需要关联Pod的场景中可以使用此类型 #不需要使用负载均衡
service -> endpoints -> pod
endpoints与service是同步创建同步删除的资源类型

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

headless service的使用场景?
仅仅需要关联Pod的场景中可以使用此类型 #不需要使用负载均衡
service -> endprints -> pod
endpoints与service是同步创建同步删除的资源类型


[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


#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    #与 kubectl get svc查到clusterip一样
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  #与kubectl get pods -o wide 查到的ip一样
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>

扩展

1、Endpoint

命名空间级资源,如果endpoints和service是同一个名字,那么就自动关联。

Endpointkubernetes中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址,它是根据service配置文件中selector描述产生的。

一个Service由一组Pod组成,这些Pod通过Endpoints暴露出来,Endpoints是实现实际服务的端点集合。换句话说,service和pod之间的联系是通过endpoints实现的。

功能一:与service做负载均衡

功能二:将外部服务引入集群

windows server 磁盘负载均衡 service负载均衡_IP_11

2、负载分发策略

对Service的访问被分发到了后端的Pod上去,目前kubernetes提供了两种负载分发策略:

  • 如果不定义,默认使用kube-proxy的策略,比如随机、轮询
  • 基于客户端地址的会话保持模式,即来自同一个客户端发起的所有请求都会转发到固定的一个Pod上

此模式可以使在spec中添加sessionAffinity:ClientIP选项

# 1、查看ipvs的映射规则【rr 轮询】
[root@k8s-m-01 ~]# ipvsadm -Ln
TCP  10.97.97.97:80 rr
  -> 10.244.1.84:80               Masq    1      0          0         
  -> 10.244.1.85:80               Masq    1      0          0         
  -> 10.244.2.83:80               Masq    1      0          0 

# 2、循环访问测试
[root@k8s-m-01 ~]# while true;do curl 10.97.97.97:80; sleep 2; done;
10.244.2.83
10.244.1.84
10.244.1.85
10.244.2.83
10.244.1.84
10.244.1.85

# 3、修改分发策略
sessionAffinity:ClientIP

# 4、查看ipvs规则【persistent 代表持久】
[root@k8s-m-01 ~]# ipvsadm -Ln
TCP  10.97.97.97:80 rr
  -> 10.244.1.84:80               Masq    1      0          0         
  -> 10.244.1.85:80               Masq    1      0          0         
  -> 10.244.2.83:80               Masq    1      0          0 

# 5、循环访问测试
[root@k8s-m-01 ~]# while true;do curl 10.97.97.97:80; sleep 5; done;
10.244.2.83
10.244.1.84
10.244.1.85
  
# 6、删除service
[root@k8s-m-01 ~]# kubectl delete -f service-clusterip.yaml
service "service-clusterip" deleted

3、HeadLiness类型的Service 常用

在某些场景中,开发人员可能不想使用Service提供的负载均衡功能,而希望自己来控制负载均衡策略,针对这种情况**,kubernetes提供了HeadLiness Service**,这类Service不会分配Cluster IP,如果想要访问service只能通过service的域名进行查询。

创建service-headliness.yaml
apiVersion: v1
kind: Service
metadata:
  name: service-headliness
  namespace: dev
spec:
  selector:
    app: nginx-pod
  clusterIP: None # 将clusterIP设置为None,即可创建headliness Service
  type: ClusterIP
  ports:
  - port: 80    
    targetPort: 80
# 1、创建service
[root@k8s-m-01 ~]# kubectl create -f service-headliness.yaml
service/service-headliness created

# 2、获取service, 发现CLUSTER-IP未分配
[root@k8s-m-01 ~]# kubectl get svc service-headliness -n dev -o wide
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE   SELECTOR
service-headliness   ClusterIP   None         <none>        80/TCP    11s   app=nginx-pod

# 3、查看service详情
[root@k8s-m-01 ~]# kubectl describe svc service-headliness  -n dev
Name:              service-headliness
Namespace:         dev
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx-pod
Type:              ClusterIP
IP:                None
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.39:80,10.244.1.40:80,10.244.2.33:80
Session Affinity:  None
Events:            <none>

# 4、查看域名的解析情况
[root@k8s-m-01 ~]# kubectl exec -it pc-deployment-66cb59b984-8p84h -n dev /bin/sh
/ # cat /etc/resolv.conf
nameserver 10.96.0.10
search dev.svc.cluster.local svc.cluster.local cluster.local
安装dig命令: # yum install bind-utils

[root@k8s-m-01 ~]# dig @10.96.0.10 service-headliness.dev.svc.cluster.local
service-headliness.dev.svc.cluster.local. 30 IN	A 10.244.1.86
service-headliness.dev.svc.cluster.local. 30 IN	A 10.244.2.84
service-headliness.dev.svc.cluster.local. 30 IN	A 10.244.1.87