K8s之Service四层代理入门实战详解

这篇具有很好参考价值的文章主要介绍了K8s之Service四层代理入门实战详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、Service四层代理概念、原理

官网中文参考文档:

1、Service四层代理概念

在K8S中Pod是有生命周期的,如果重启Pod如果Pod重启它的IP很有可能会发生变化,如果我们程序中指定Pod地址是写死的,Pod每升级一次,刚升级的Pod,集群中其他关联此Pod的服务就找不到升级的Pod。

为了解决上面问题,在K8S集群中定义了Service资源对象(简写svc),Service的IP地址是不会随便改动的,相当于定义了一个服务的入口,客户端或者集群中其他组件通过连接Service,Service代理到后端相应的服务实例,Service是一组Pod的集合,这组Pod能够被Service访问到,通常是通过标签关联实现的。

小结:

1、Pod IP地址经常发生变化,Service代理Pod,我们客户端访问,只需要访问Service,Service代理到后端Pod。

2、通过Pod IP在K8S集群之外是无法访问到的,所以需要创建Service,这个Service可以在K8s集群外部访问。

2、Service工作原理

  • k8s在创建Service时,会根据标签选择器selector(lable selector)来查找Pod,据此创建与Service同名的endpoint对象。

  • 当Pod 地址发生变化时,endpoint也会随之发生变化,service接收前端client请求的时候,就会通过endpoint,找到转发到哪个Pod进行访问的地址。(至于转发到哪个节点的Pod,由负载均衡kube-proxy决定)

小结:

具体来说,当一个Pod被创建并加入到Service中时,Kubernetes会为该Pod创建一个Endpoint对象,Endpoint对象包含了Pod的IP地址和端口号。当请求到达Service的Cluster IP地址时,ipvs(iptables)规则会将请求转发到对应的Endpoint上,从而实现了四层代理的功能。

3、Service原理解读

K8s之Service四层代理入门实战详解

  • Service是一个固定接入层,客户端通过访问ServiceIP+端口,从而访问到后端关联的Pod资源,Service的工作需要依赖于K8S集群中的DNS服务,不同版本的K8S集群,使用的DNS服务也是不同的,1.11之前版本使用kubeDNS,较新版本使用coreDNS。

  • Service的域名解析需要依赖于DNS服务,而DNS服务需要依赖于网络插件(flannel、calico)等,因此在部署K8S集群后也需要部署网络插件。

  • K8s节点上kube-proxy这个组件将始终监视着apiserver中有关service资源的变动信息,需要跟master之上的apiserver交互,随时连接到apiserver上获取任何一个与service资源相关的资源变动状态,这种是通过kubernetes中固有的一种请求方法watch(监视)来实现,一旦有service资源的内容发生变动(如创建,删除),kube-proxy都会将它转化成当前节点之上的能够实现service资源调度,把我们请求调度到后端特定的pod资源之上的规则,这个规则可能是iptables,也可能是ipvs,取决于service的实现方式。

4、Service四种类型

  • ClusterIP:默认类型,只能在集群内部访问,通过ClusterIP暴露服务,可以在集群内部的其他Pod中访问该服务。
  • NodePort:在ClusterIP的基础上,通过NodePort将服务暴露到集群外部,可以通过NodeIP:NodePort的方式访问服务。
  • ExternalName:将服务映射到集群外部的DNS记录,可以通过服务名称直接访问外部服务,应用在夸名称空间访问。

二、Service四层代理三种类型案例

1、创建ClusterIP类型Service

默认类型,只能在集群内部访问,通过ClusterIP暴露服务,可以在集群内部的其他Pod中访问该服务。

cat clusterip-deploy.yaml 

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-cluster
  namespace: default
  labels:
    type: web-cluster
    env: uat
spec:
  selector:
    matchLabels:
      type: web-cluster
      env: uat
  replicas: 3 
  template:
    metadata:
      namespace: default
      labels:
        type: web-cluster
        env: uat
    spec:
      containers:
      - name: web-cluster
        image: nginx
        imagePullPolicy: IfNotPresent 
        startupProbe:
          tcpSocket:
            port: 80
        readinessProbe:
          httpGet:
            port: 80
            path: "index.html"
        livenessProbe:
          httpGet:
            port: 80
            path: "index.html"

service资源清单如下:

cat clusterip-svc.yaml 

---
apiVersion: v1
kind: Service
metadata:
  name: web-clusterip
  namespace: default
  labels:
    env: uat
spec:
  type: ClusterIP     # ClusterIP类型
  ports:
  - port: 80          # SVC端口
    protocol: TCP     # TCP协议
    targetPort: 80    # Pod暴露端口
  selector:           # 关联具有以下标签的Pod
    env: uat
    type: web-cluster

执行YAML文件 && 查看资源

kubectl apply -f clusterip-deploy.yaml -f clusterip-svc.yaml 
kubectl get pods,svc

查看Service Endpoints 是否关联上Pod

kubectl describe svc web-clusterip

K8s之Service四层代理入门实战详解

获取Service IP地址,通过Service代理访问后端Pod

kubectl get svc web-clusterip|awk NR==2|awk '{print $3}'
10.103.211.187
curl 10.103.211.187

K8s之Service四层代理入门实战详解

2、创建NodePort类型Service

在ClusterIP的基础上,通过NodePort将服务暴露到集群外部,可以通过NodeIP:NodePort的方式访问服务。

创建NodePort类型svc关联标签具有 app=demo-nginx

Deployment资源清单如下:

cat nodeport-deploy.yaml 

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-nodeport
  namespace: default
  labels:
    app: web-nodeport
    env: uat
spec:
  selector:
    matchLabels:
      app: web-nodeport
      env: uat
  replicas: 3
  template:
    metadata:
      namespace: default
      labels:
        app: web-nodeport
        env: uat
    spec:
      containers:
      - name: uat-nginx
        image: nginx
        imagePullPolicy: IfNotPresent 
        startupProbe:
          tcpSocket:
            port: 80
        readinessProbe:
          httpGet:
            port: 80
            path: "index.html"
        livenessProbe:
          httpGet:
            port: 80
            path: "index.html"

Service资源清单如下:

cat nodeport-svc.yaml 

---
apiVersion: v1
kind: Service
metadata:
  name: nodeport-svc
  namespace: default
  labels:
    env: uat
spec:
  type: NodePort
  ports:
  - port: 80               # svc的端口,这个是k8s集群内部服务可访问的端口
    protocol: TCP          # 协议
    targetPort: 80         # Pod上端口
    nodePort: 30303        # Node节点暴露端口
  selector:                # 关联具有app=web-nginx && env=uat 的Pod
    app: web-nodeport
    env: uat

执行YAML清单 && 查看状态

kubectl apply -f nodeport-deploy.yaml 
kubectl apply -f nodeport-svc.yaml 
kubectl get pods,svc

查看Service的Endpoints是否关联上Pod

kubectl describe svc nodeport-svc|grep Endpoints

K8s之Service四层代理入门实战详解

通过浏览器访问NodeIP:30303

K8s之Service四层代理入门实战详解

3、创建ExternalName类型Service

将服务映射到集群外部的DNS记录,可以通过服务名称直接访问外部服务。

应用场景:跨名称空间关联,ExternalName可以理解成软链接SVC资源

需求:default名称空间下的client服务要可以访问nginx-ns名称空间下的nginx-svc服务,实验图如下:

K8s之Service四层代理入门实战详解

创建 服务端相关资源,并放在 nginx-ns 命名空间下

cat nginx-server.yaml 

---
apiVersion: v1
kind: Namespace
metadata:
  name: nginx-ns
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-server
  namespace: nginx-ns
  labels:
    app: nginx-server
    env: uat
spec:
  selector:
    matchLabels:
      app: nginx-server
      env: uat
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx-server
        env: uat
    spec:
      containers:
      - name: nginx-server
        image: nginx
        imagePullPolicy: IfNotPresent 
        startupProbe:
          tcpSocket:
            port: 80
        readinessProbe:
          httpGet:
            port: 80
            path: "index.html"
        livenessProbe:
          httpGet:
            port: 80
            path: "index.html"
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
  namespace: nginx-ns
spec:
  ports:
  - name: http
    port: 80              
    protocol: TCP        
  selector:           
    app: nginx-server 
    env: uat
kubectl apply -f nginx-server.yaml 

创建 客户端 Pod资源:

cat nginx-client.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-client
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-client
  template:
    metadata:
      labels:
        app: nginx-client
    spec:
      containers:
      - name: nginx-client
        image: busybox:1.28
        imagePullPolicy: IfNotPresent
        command: ["/bin/sh", "-c", "sleep 3600000"]
kubectl apply -f nginx-client.yaml

创建 ExternalName 类型 Service,链接到 nginx-ns 名称空间下的nginx-svc Service

cat nginx-client-svc.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: client-nginx
spec:
  type: ExternalName
  externalName: nginx-svc.nginx-ns.svc.cluster.local # 访问此SVC链接到nginx-svc.nginx-ns.svc.cluster.local SVC
  ports:
  - name: http
    port: 80
    targetPort: 80
kubectl apply -f nginx-client-svc.yaml

查看Service详细信息:

kubectl describe svc client-nginx

K8s之Service四层代理入门实战详解

测试:进入client端访问nginx-service网站

kubectl exec -it nginx-client-784fd7bfc7-2d892 -- /bin/sh
wget -q -O - client-nginx

K8s之Service四层代理入门实战详解

三、拓展

1、Service域名解析

Service只要创建成功,我们就可以直接通过他的域名来访问(在Pod内可以使用域名访问,在Node节点是不可以使用域名访问的),每个服务创建后都会在集群DNS中动态添加一个资源记录,添加完成后就可以解析了,资源记录的格式是:

SVC_NAME.NS_NAME.DOMAIN.LTD.
服务名.命名空间.域名后缀
集群默认的域名后缀是svc.cluster.local.

用上面的 创建ClusterIP类型svc 来做实验,在Pod中使用域名访问。

kubectl exec -it web-cluster-5db6bc847b-226k9 -- /bin/bash
curl web-clusterip.default.svc.cluster.local

K8s之Service四层代理入门实战详解

2、自定义Endpoints资源

场景:创建Service资源,代理本机的3306端口

首先在宿主机安装、启动MySQL服务

yum install mariadb-server.x86_64 -y
systemctl start mariadb
systemctl enable mariadb

创建Service代理3306端口 YAML如下:

cat 3306-svc.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: svc-3306
spec:
  type: ClusterIP
  ports:
  - port: 3306
kubectl apply -f 3306-svc.yaml	

我们svc中没有定义关联的Pod标签,所以svc中并Endpoint为none

kubectl describe svc svc-3306

K8s之Service四层代理入门实战详解

创建 Endpoint资源 并关联上面的SVC

cat 3306-ep.yaml 
---
apiVersion: v1
kind: Endpoints
metadata:
  name: svc-3306 # ep的名称必须和svc一致,通过名称相关联
subsets:
- addresses:
  - ip: 172.21.0.13
  ports:
  - port: 3306

OK,此时我们查看SVC的 Endpoint 会关联上面创建的Endpoint,后续K8S集群连接MySQL服务直接可以写SVC的IP+端口进行访问了。

kubectl describe svc svc-3306

K8s之Service四层代理入门实战详解文章来源地址https://www.toymoban.com/news/detail-477176.html

到了这里,关于K8s之Service四层代理入门实战详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • k8s之Service详解

        Kubernetes Serivce是一组具有相同label Pod集合的抽象(可以简单的理解为集群内的LB),集群内外的各个服务可以通过Service进行互相通信。 Service创建 当用户在kubernetes集群中创建了含有label的Service之后,同时会在集群中创建出一个同名的Endpoints对象,用于存储该Service下的Pod I

    2024年02月16日
    浏览(34)
  • K8s Service网络详解(二)

    Kubernetes 在设计之初就充分考虑了针对容器的 服务发现 与 负载均衡 机制。 Service 资源,可以通过 kube-proxy 配合 cloud provider 来适应不同的应用场景。 Service相关的事情都由Node节点上的 kube-proxy处理。在Service创建时Kubernetes会分配IP给Service,同时通过API Server通知所有kube-proxy有新

    2024年02月15日
    浏览(54)
  • 详解K8S网络模型(包含Service讲解)

    无意中翻阅官方文档,看到了Kubernetes中的网络模型, 于是,开始学习,分享如下。 官方文档: 网络模型https://kubernetes.io/docs/concepts/services-networking/ Servicehttps://kubernetes.io/docs/concepts/services-networking/service/ 集群中的每个Pod会在集群范围内获取自己唯一的IP地址。 因此,Pod间不需

    2024年02月07日
    浏览(38)
  • k8s服务发现之第二弹Service详解

    Kubernetes Servies 是一个 RESTFul 接口对象,可通过 yaml 文件创建。 例如,假设您有一组 Pod: 每个 Pod 都监听 9376 TCP 端口 每个 Pod 都有标签 app=MyApp 上述 YAML 文件可用来创建一个 Service: 名字为 my-service 目标端口为 TCP 9376 选取所有包含标签 app=MyApp 的 Pod 关于 Service,您还需要了解

    2024年02月16日
    浏览(47)
  • k8s 入门到实战--部署应用到 k8s

    k8s 入门到实战 01.png 本文提供视频版: 最近这这段时间更新了一些 k8s 相关的博客和视频,也收到了一些反馈;大概分为这几类: 公司已经经历过服务化改造了,但还未接触过云原生。 公司部分应用进行了云原生改造,但大部分工作是由基础架构和运维部门推动的,自己只

    2024年02月09日
    浏览(40)
  • K8S 入门实战(3)

    上篇文章记录了 kubeadm 工具搭建 kubernetes 集群的过程,本文记录 K8S 一些核心概念以及各个组件是如何协调工作的。 1. K8S 核心架构 K8S 采用了 控制面 / 数据面 (Control Plane / Data Plane)架构,集群中的 主机 被称为节点,主机可以是物理机也可以是虚拟机。其中控制节点叫做

    2024年01月24日
    浏览(35)
  • Kubernetes(k8s)实战:深入详解Volume,详解k8s文件同步存储

    Volume官网:https://kubernetes.io/docs/concepts/storage/volumes/ On-disk files in a Container are ephemeral, which presents some problems for non-trivial applications when running in Containers. First, when a Container crashes, kubelet will restart it, but the files will be lost - the Container starts with a clean state. Second, when running Containers to

    2024年02月13日
    浏览(47)
  • K8S系列二:实战入门

    本文是K8S系列第二篇,主要面向对K8S新手同学,阅读本文需要读者对K8S的基本概念,比如Pod、Deployment、Service、Namespace等基础概念有所了解。尚且不熟悉的同学推荐先阅读本系列的第一篇文章:《K8S系列一:概念入门》 本文旨在讲述如何通过kubectl(kubernetes命令行工具)操作

    2024年02月13日
    浏览(49)
  • 【Java】基于fabric8io库操作k8s集群实战(pod、deployment、service、volume)

    一开始了解到Java Api库操作k8s集群,有两个,分别为: kubernetes-client/java fabric8io/kubernetes-client 但个人对比使用了两个发现,还是 fabric8io更易用 ,用的人多是有道理的, fabric8io和yaml文件十分贴切 ,所以 通俗易懂 。本文前提是已配置好集群,已经熟悉了kubectl工具常用命令。

    2024年02月02日
    浏览(47)
  • Kubernetes、k8s从入门到实战

    本文章用到k8s安装包及工具文件链接:https://pan.baidu.com/s/1gYU9xxwxI9cXfJ1IJGQjwg?pwd=ye11 提取码:ye11 我们对于云计算的概念,维基百科有以下定义: Cloud computing is a new form of Internet-based computing that provides shared computer processing resources and data to computers and other devices on demand. 云计算就是

    2024年01月19日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包