概念、原理解读

1、 为什么要有Service?

  • pod的IP经常变化,service是pod的代理,客户端访问只需要访问service,就会把请求代理到Pod
  • pod的IP在k8s集群之外无法访问,所以需要创建service,这个service可以在k8s集群外访问的。

2、 Service概述

  • service是一个固定接入层,客户端可以通过访问service的IP和端口进而访问到service关联的一组后端pod。
  • service的名称解析依赖于在kubernetes集群之上部署的一个附件,kubernetes的dns服务(1.11之前的版本使用的是kubedns,较新的版本使用的是coredns),因此在部署完k8s之后需要再部署dns附件。
  • kubernetes要想给客户端提供网络功能,需要依赖第三方的网络插件(flannel,calico等)。每个K8s节点上都有一个组件叫做kube-proxy这个组件将始终监视着apiserver中有关service资源的变动信息,通过kubernetes中固有的一种请求方法watch来实现监视,一旦有service资源的内容发生变动(如创建,删除),kube-proxy都会将它转化成当前节点之上的能够实现service资源调度,把我们请求调度到后端特定的pod资源之上的规则,这个规则可能是iptables,也可能是ipvs,取决于service的实现方式。

3、 Service工作原理

k8s在创建Service时,会根据标签选择器selector(lable selector)来查找Pod,并创建endpoint对象来存储pod集合的IP+端口信息,当Pod 地址发生变化时,endpoint也会随之发生变化,service接收前端client请求的时候,就会通过endpoint,找到转发到哪个Pod进行访问的地址。(至于转发到哪个节点的Pod,由负载均衡kube-proxy决定)
如图:
在这里插入图片描述
在这里插入图片描述

4 、kubernetes集群中有三类IP地址

1、Node Network(节点网络):物理节点或者虚拟节点的网络,如ens33接口上的网路地址
在这里插入图片描述

2、Pod network(pod 网络),创建的Pod具有的IP地址

 kubectl get pods -o wide

在这里插入图片描述
Node Network和Pod network这两种网络地址是配置的,其中节点网络地址是配置在节点接口之上,而pod网络地址是配置在pod资源之上的,因此这些地址都是配置在某些设备之上的,这些设备可能是硬件,也可能是软件模拟的
3、Cluster Network(也称为service network,表示集群地址),这个地址是虚拟的地址(virtual ip),没有配置在某个接口上,只是出现在service的规则当中。

kubectl get svc

在这里插入图片描述

认识Service资源

查看定义Service资源需要的字段有哪些?

kubectl explain service

在这里插入图片描述
其中

FIELDS:
   apiVersion	<string>  #service资源使用的api组
   kind	<string>           #创建的资源类型
   metadata	<Object>      #定义元数据
   spec	<Object>   
kubectl explain service.spec
其中
FIELDS:
  type	<string>  #定义service的类型
ports	<[]Object>  #定义service端口,用来和后端pod建立联系

Service的四种类型

查看定义Service.spec.type有哪些类型?

kubectl explain service.spec.type

在这里插入图片描述

Service的端口

查看service的spec.ports字段如何定义?

kubectl explain service.spec.ports
其中
FIELDS:
   appProtocol	<string>
   name	<string>  #定义端口的名字
   nodePort	<integer>   #service在物理机映射的端口,默认在 30000-32767 之间
   port	<integer> -required-  #service的端口,这个是k8s集群内部服务可访问的端口
   protocol	<string>
   targetPort	<string> # targetPort是pod上的端口,从port和nodePort上来的流量,经过kube-proxy流入到后端pod的targetPort上,最后进入容器。

创建Service

创建Pod

mkdir pods 
vim pod_test_1.yaml

【pod_test_1.yaml】 文件内容

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-test-1
spec:
  selector:
    matchLabels:
      test: cluster
  replicas: 2
  template:
    metadata:
      labels:
        test: cluster
    spec:
      containers:
      - name: my-nginx
        image: docker.io/library/nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80  #pod中的容器需要暴露的端口
        startupProbe:
           periodSeconds: 5
           initialDelaySeconds: 60
           timeoutSeconds: 10
           httpGet:
             scheme: HTTP
             port: 80
             path: /
        livenessProbe:
           periodSeconds: 5
           initialDelaySeconds: 60
           timeoutSeconds: 10
           httpGet:
             scheme: HTTP
             port: 80
             path: /
        readinessProbe:
           periodSeconds: 5
           initialDelaySeconds: 60
           timeoutSeconds: 10
           httpGet:
             scheme: HTTP
             port: 80
             path: /

更新资源清单文件

kubectl apply -f pod_test_1.yaml

在这里插入图片描述
查看刚才创建的Pod ip地址

kubectl get pods -owide -l test=cluster

在这里插入图片描述

创建service

vim service_test_1.yaml

【service_test_1.yaml】 文件内容

apiVersion: v1
kind: Service
metadata:
  name: nginx-test-1
  labels:
    test: cluster
spec:
  type: ClusterIP
  ports:
  - port: 80   #service的端口,暴露给k8s集群内部服务访问
    protocol: TCP
    targetPort: 80    #pod容器中定义的端口
  selector:
    test: cluster  #选择拥有test=cluster标签的pod
kubectl apply -f service_test_1.yaml
kubectl get svc -l test=cluster

在这里插入图片描述
在k8s控制节点(master节点)访问service的IP+端口,就可以把请求代理到后端pod

curl 10.111.10.207:80

在这里插入图片描述

查看service详细信息

kubectl describe svc nginx-test-1

在这里插入图片描述
观察转发情况

ipvsadm -Ln

在这里插入图片描述
查看endpoint

kubectl get ep nginx-test-1

在这里插入图片描述
service可以对外提供统一固定的ip地址,并将请求重定向至集群中的pod。其中“将请求重定向至集群中的pod”就是通过endpoint与selector协同工作实现。selector是用于选择pod,由selector选择出来的pod的ip地址和端口号,将会被记录在endpoint中。endpoint便记录了所有pod的ip地址和端口号。当一个请求访问到service的ip地址时,就会从endpoint中选择出一个ip地址和端口号,然后将请求重定向至pod中。具体把请求代理到哪个pod,需要的就是kube-proxy的轮询实现的。service不会直接到pod,service是直接到endpoint资源,就是地址加端口,再由endpoint再关联到pod。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐