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。

相关推荐
wuxinyan1232 小时前
Java面试题51:一文深入了解K8s 环境下企业级 CI/CD 流水线搭建
java·ci/cd·kubernetes·面试题
安逸sgr3 小时前
Hermes Agent + Obsidian 打造第二大脑(三):Docker 部署详解——从零到生产环境的完整实战指南!
运维·docker·容器·obsidian·hermes·hermesagent
小夏子_riotous4 小时前
Docker学习路径——9、Docker 网络深度解析:从默认网络到自定义网络实战
linux·运维·网络·docker·容器·centos·云计算
步步为营DotNet4 小时前
.NET 11 与 C# 14 助力云原生应用安全架构升级
云原生·c#·.net
身如柳絮随风扬4 小时前
Kubernetes v1.24 从入门到实战:核心概念与集群管理详解
云原生·容器·kubernetes
剩下了什么4 小时前
微服务入门介绍
微服务·云原生·架构
wuxinyan1234 小时前
Java面试题52:一文深入了解Kubernetes 核心资源对象
java·kubernetes·面试题
小义_19 小时前
【Kubernetes】(九)Service 2
云原生·容器·kubernetes
Cyber4K21 小时前
【Kubernetes专项】温故而知新,重温技术原理(2)
云原生·容器·kubernetes
雨奔1 天前
Kubernetes 网络策略(NetworkPolicy)完全指南:声明式 Pod 通信管控
网络·容器·kubernetes