K8S四层代理Service-01

K8S四层代理Service-01

概念、原理解读

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地址

bash 复制代码
 kubectl get pods -o wide

Node Network和Pod network这两种网络地址是配置的,其中节点网络地址是配置在节点接口之上,而pod网络地址是配置在pod资源之上的,因此这些地址都是配置在某些设备之上的,这些设备可能是硬件,也可能是软件模拟的

3、Cluster Network(也称为service network,表示集群地址),这个地址是虚拟的地址(virtual ip),没有配置在某个接口上,只是出现在service的规则当中。

bash 复制代码
kubectl get svc

认识Service资源

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

bash 复制代码
kubectl explain service

其中

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

Service的四种类型

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

bash 复制代码
kubectl explain service.spec.type

Service的端口

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

bash 复制代码
kubectl explain service.spec.ports
bash 复制代码
其中
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

bash 复制代码
mkdir pods 
vim pod_test_1.yaml

【pod_test_1.yaml】 文件内容

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: /

更新资源清单文件

bash 复制代码
kubectl apply -f pod_test_1.yaml

查看刚才创建的Pod ip地址

bash 复制代码
kubectl get pods -owide -l test=cluster

创建service

bash 复制代码
vim service_test_1.yaml

【service_test_1.yaml】 文件内容

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
bash 复制代码
kubectl apply -f service_test_1.yaml
kubectl get svc -l test=cluster

在k8s控制节点(master节点)访问service的IP+端口,就可以把请求代理到后端pod

bash 复制代码
curl 10.111.10.207:80

查看service详细信息

bash 复制代码
kubectl describe svc nginx-test-1

观察转发情况

bash 复制代码
ipvsadm -Ln

查看endpoint

bash 复制代码
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。

相关推荐
€☞扫地僧☜€3 小时前
docker 拉取MySQL8.0镜像以及安装
运维·数据库·docker·容器
全能全知者4 小时前
docker快速安装与配置mongoDB
mongodb·docker·容器
为什么这亚子5 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
ZHOU西口7 小时前
微服务实战系列之玩转Docker(十八)
分布式·docker·云原生·架构·数据安全·etcd·rbac
牛角上的男孩8 小时前
Istio Gateway发布服务
云原生·gateway·istio
JuiceFS9 小时前
好未来:多云环境下基于 JuiceFS 建设低运维模型仓库
运维·云原生
景天科技苑10 小时前
【云原生开发】K8S多集群资源管理平台架构设计
云原生·容器·kubernetes·k8s·云原生开发·k8s管理系统
wclass-zhengge11 小时前
K8S篇(基本介绍)
云原生·容器·kubernetes
颜淡慕潇11 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
川石课堂软件测试13 小时前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana