K8s-----(六)Service的类型

K8s------Service

  • 1 Service的介绍
    • 1.1 为什么要使用Service
    • 2 service的类型
  • 2 集群内部访问
    • 2.1 IPVS模式的service
    • 2.2 Headless Service
  • 3 集群外部访问Service
    • 3.1 NodePort方式
    • 3.2 ExternalName
  • 4 从内部访问外部

1 Service的介绍

Kubernetes Pod是有生命周期的,它们可以被创建,也可以被销毁,然而一旦被销毁生命就永远结束。 通过ReplicationController能够动态地创建和销毁Pod, 每个 Pod 都会获取它自己的 IP 地址,可一旦销毁后,重新创建后,IP地址会产生改变。 这会导致一个问题:在 Kubernetes 集群中,如果一组 Pod(称为 backend)为其它 Pod (称为 frontend)提供服务,一旦backend的Pod重新创建,那么frontend的Pod该如何发现,并连接到这组 Pod 中的哪些 backend 呢?

1.1 为什么要使用Service

Service资源用于为pod对象提供一个固定、统一的访问接口及负载均衡的能力,并借助新一代DNS系统的服务发现功能,解决客户端发现并访问容器化应用的问题。

在kubernetes中,在收到rc调控的时候,pod副本数是变化的,对应的虚IP也是变化的,比如发生迁移或者伸缩时。这对于pod的访问来说是不能接受的,kubernetes中的service是一种逻辑概念。它定义了一个pod逻辑集合以及访问它们的策略,service与pod的关联同样是通过label完成的。service的目标是提供一种桥梁,他会为访问者提供一个固定的访问IP地址,用于在访问时重定向到相应的后端,这可以使一些非kubernetes原生应用程序,在无需为kubernetes编写特定代码的前提下轻松访问后端。

注意: service只是在k8s集群内部起作用,集群外部访问是无效的

  • Service可以看作是一组提供相同服务的Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。
  • Service默认只支持4层负载均衡能力,没有7层功能。(可以通过Ingress实现)

2 service的类型

  • ClusterIP:默认值,k8s系统给service自动分配的虚拟IP,只能在集群内部访问。一个Service可能对应多个EndPoint(Pod),client访问的是Cluster IP,通过iptables规则转到Real Server,从而达到负载均衡的效果
  • NodePort:将Service通过指定的Node上的端口暴露给外部,访问任意一个
  • NodeIP:nodePort都将路由到ClusterIP。
  • LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到:NodePort,此模式只能在云服务器上使用。
  • ExternalName:将服务通过 DNS CNAME记录方式转发到指定的域名(通过 spec.externlName 设定)

2 集群内部访问

Service 是由 kube-proxy 组件,加上 iptables 来共同实现的.

## 创建控制器
kubectl create deployment nginx --image=myapp:v1 --replicas=3 
## 暴露服务的80端口
kubectl expose deployment nginx --port=80 
kubectl get pod ## 查看pod的信息
## 查看nginx服务的信息,类型ClusterIP:k8s系统给service自动分配的虚拟IP,只能在集群内部访问
kubectl describe svc nginx 

K8s-----(六)Service的类型_第1张图片

  • 查看iptables的规则:iptables -t nat -nL |grep 80,iptables 使用NAT等技术将virtualIP的流量转至endpoint中,容器内暴露的端口是80

在这里插入图片描述

  • kube-proxy 通过 iptables 处理 Service 的过程,需要在宿主机上设置相当多的 iptables规则,如果宿主机有大量的Pod,不断刷新iptables规则,会消耗大量的CPU资源

2.1 IPVS模式的service

IPVS模式的service,可以使K8s集群支持更多量级的Pod

pod和service通信: 通过iptables或ipvs实现通信,ipvs取代不了iptables,因为ipvs只能做负载均衡,而做不了nat转换

(1)开启kube-proxy的ipvs模式

  • 所有节点安装ipvsadm:yum install ipvsadm -y
  • 修改IPVS模式:kubectl edit cm kube-proxy -n kube-system

K8s-----(六)Service的类型_第2张图片

  • 更新kube-proxy pod:
kubectl get pod -n kube-system |grep kube-proxy |awk '{system("kubectl delete pod "$1" -n kube-system")}'

在这里插入图片描述

  • IPVS模式下,kube-proxy会在service创建后,在宿主机上添加一个虚拟网卡:kube-ipvs0,并分配service IP

K8s-----(六)Service的类型_第3张图片
(3)应用文件:kubectl apply -f demo.yml

---
apiVersion: v1
kind: Service  ## 服务
metadata:
  name: myservice
spec:
  selector:
    app: myapp
  ports:
 - protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment  ## 控制器创建pod
metadata:
  name: deployment
spec:
  replicas: 5  ## 副本数
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v1
  • 查看服务的信息:kubectl get svc

在这里插入图片描述

  • IPVS模式下,kube-proxy会在service创建后,在宿主机上添加一个虚拟网卡:kube-ipvs0,并分配service IP
    查看IP信息:ip addr

在这里插入图片描述

  • kube-proxy通过IPVS模块,以rr轮询方式调度service中的Pod
    查看当前配置的虚拟服务和各个RS的权重:ipvsadm -ln

K8s-----(六)Service的类型_第4张图片

(2)扩容:

  • 编辑文件:vim demo.yml

K8s-----(六)Service的类型_第5张图片

  • 应用文件:kubectl apply -f demo.yml,扩容成功

K8s-----(六)Service的类型_第6张图片

  • 查看当前配置的虚拟服务和各个RS的权重:ipvsadm -ln
  • 查看指定命名空间pod的详细信息:kubectl -n kube-system get pod -o wide

K8s-----(六)Service的类型_第7张图片

  • 查看指定命名空间的服务:kubectl -n kube-system get svc

在这里插入图片描述

  • 进入容器的交互界面:kubectl attach demo -c demo -it,访问服务时是负载均衡的

K8s-----(六)Service的类型_第8张图片

2.2 Headless Service

Headless Service不需要分配一个VIP,而是直接以DNS记录的方式解析出被代理Pod的IP地址。

headless使用场景

第一种:自主选择权,client自己来决定使用哪个Real Server,可以通过查询DNS来获取Real Server的信息。

第二种:Headless Service的对应的每一个Endpoints,即每一个Pod,都会有对应的DNS域名;这样Pod之间就能互相访问,集群也能单独访问pod

  • 域名格式:$(servicename).$(namespace).svc.cluster.local

(1)应用文件:kubectl apply -f demo.yml ,修改上面实验中的demo.yml中service的类型为None

clusterIP: None表示是无头service
port: 80  service ip中的端口
targetPort: 80 容器ip中的端口

K8s-----(六)Service的类型_第9张图片

  • 查看服务的信息:kubectl get svc

在这里插入图片描述

  • 查看当前配置的虚拟服务和各个RS的权重:ipvsadm -ln

K8s-----(六)Service的类型_第10张图片

  • 查看IP的信息:ip addr

在这里插入图片描述

  • 查看服务的详细信息:kubectl describe svc myservice

K8s-----(六)Service的类型_第11张图片

  • 查看指定命名空间的服务:kubectl -n kube-system get svc
  • 查看DNS中的A记录:dig -t A myservice.default.svc.cluster.local @10.96.0.10,Real Server的信息

K8s-----(六)Service的类型_第12张图片

  • 查看指定服务的信息:kubectl describe -n kube-system svc kube-dns

K8s-----(六)Service的类型_第13张图片
(2)测试:在容器中访问myservice服务,是负载均衡的
K8s-----(六)Service的类型_第14张图片
在这里插入图片描述
(3)Pod滚动更新后,依然可以解析:

  • 应用文件:kubectl apply -f demo.yml

K8s-----(六)Service的类型_第15张图片

  • 进入容器的交互式模式:kubectl attach demo -c demo -it,依然可以通过服务的名字访问服务后端的pod,实现负载均衡

K8s-----(六)Service的类型_第16张图片

3 集群外部访问Service

3.1 NodePort方式

Kubernetes 的控制器能保证在任意副本(Pod)挂掉时自动从其他机器启动一个新的,还可以动态扩容等,通俗地说,这个 Pod 可能在任何时刻出现在任何节点上,也可能在任何时刻死在任何节点上;那么自然随着 Pod 的创建和销毁,Pod IP 肯定会动态变化;那么如何把这个动态的 Pod IP 暴露出去?这里借助于 Kubernetes 的 Service 机制,Service 可以以标签的形式选定一组带有指定标签的 Pod,并监控和自动负载他们的 Pod IP,那么我们向外暴露只暴露 Service IP 就行了。

这就是 NodePort 模式:即在每个节点上开起一个端口,然后转发到内部 Pod IP 上
K8s-----(六)Service的类型_第17张图片
(1)应用文件:kubectl apply -f demo.yml

  • 将服务的类型设定为NodePort 模式

K8s-----(六)Service的类型_第18张图片

  • 查看服务的信息:kubectl get svc,服务的80端口绑定到本机的31010端口

在这里插入图片描述

  • 查看当前配置的虚拟服务和各个RS的权重:ipvsadm -Ln,轮询的方式

在这里插入图片描述

  • 查看IP地址:ip addr

K8s-----(六)Service的类型_第19张图片

  • 查看31010端口的服务:netstat -antlp| grep 31010,将服务绑定到本地的31010端口

在这里插入图片描述

(2)测试:curl 172.25.12.2:31010/hostname.html,实现负载均衡

K8s-----(六)Service的类型_第20张图片

3.2 ExternalName

从外部访问 Service 的第二种方式

(1)应用文件:kubectl apply -f demo.yml
K8s-----(六)Service的类型_第21张图片

  • 查看服务的信息:kubectl get svc,服务的80端口绑定到本地的31199端口,外部访问的IP状态为prending

在这里插入图片描述

  • 查看当前配置的虚拟服务和各个RS的权重:ipvsadm -Ln,轮询的方式

在这里插入图片描述

  • 查看myservice服务的详细信息:kubectl describe svc myservice

K8s-----(六)Service的类型_第22张图片

(2)service允许为其分配一个公有IP

  • 重新应用文件:kubectl apply -f demo.yml

K8s-----(六)Service的类型_第23张图片

  • 查看服务的信息:kubectl get svc,服务中被分配到外部访问的VIP

在这里插入图片描述
(3)测试:curl 172.25.12.100/hostname.html,能通过外部IP访问,并且实现负载均衡

K8s-----(六)Service的类型_第24张图片

4 从内部访问外部

(1)应用文件:kubectl apply -f demo.yml

  • Service 定义将ey-service 服务映射到 www.baidu.com
apiVersion: v1
kind: Service
metadata:
  name: ex-service
spec:
  type:  ExternalName
 clusterIP:Name: www.baidu.com
  • 查看服务信息:kubectl get svc,ex-service服务的EXTERNAL-IP=www.baidu.com

在这里插入图片描述
(2)查看DNS中的A记录:dig -t A ex-service.default.svc.cluster.local @10.96.0.10

当查找主机 ex-service.default.svc.cluster.local 时,群集DNS服务返回 CNAME 记录,其值为www.baidu.com 。 访问 ex-service 的方式与其他服务的方式相同,但主要区别在于重定向发生在 DNS 级别,而不是通过代理或转发

K8s-----(六)Service的类型_第25张图片

你可能感兴趣的:(企业部分,K8s)