• 【云原生 | 从零开始学Kubernetes】十七、Kubernetes核心技术Service


    该篇文章已经被专栏《从零开始学k8s》收录
    上一篇文章:k8spod的容器探测与启动策略 点击跳转

    在这里插入图片描述

    快速了解service

    前面我们了解到 Deployment 只是保证了支撑服务的微服务Pod的数量,但是没有解决如何访问这些服务的问题。一个Pod只是一个运行服务的实例,随时可能在一个节点上停止,在另一个节点以一个新的IP启动一个新的Pod,因此不能以确定的IP和端口号提供服务。

    要稳定地提供服务需要服务发现和负载均衡能力。服务发现完成的工作,是针对客户端访问的服务,找到对应的后端服务实例。在K8S集群中,客户端需要访问的服务就是Service对象。每个Service会对应一个集群内部有效的虚拟IP,集群内部通过虚拟IP访问一个服务。

    在K8S集群中,微服务的负载均衡是由kube-proxy实现的。kube-proxy是k8s集群内部的负载均衡器。它是一个分布式代理服务器,在K8S的每个节点上都有一个;这一设计体现了它的伸缩性优势,需要访问服务的节点越多,提供负载均衡能力的kube-proxy就越多,高可用节点也随之增多。与之相比,我们平时在服务器端使用反向代理作负载均衡,还要进一步解决反向代理的高可用问题。

    Service存在的意义

    防止Pod失联【服务发现】

    因为Pod每次创建都对应一个IP地址,而这个IP地址是短暂的,每次随着Pod的更新都会变化,假设当我们的前端页面有多个Pod时候,同时后端也多个Pod,这个时候,他们之间的相互访问,就需要通过注册中心,拿到Pod的IP地址,然后去访问对应的Pod
    请添加图片描述

    定义Pod访问策略【负载均衡】

    页面前端的Pod访问到后端的Pod,中间会通过Service一层,而Service在这里还能做负载均衡,负载均衡的策略有很多种实现策略,例如:

    • 随机
    • 轮询
    • 响应比
      请添加图片描述

    Pod和Service的关系

    这里Pod 和 Service 之间还是根据 label 和 selector 建立关联的 【和Controller一样】

    请添加图片描述
    我们在访问service的时候,其实也是需要有一个ip地址,这个ip肯定不是pod的ip地址,而是 虚拟IP vip

    Service常用类型

    Service常用类型有三种

    • ClusterIp:集群内部访问
    • NodePort:对外访问应用使用
    • LoadBalancer:对外访问应用使用,公有云

    举例

    我们可以导出一个文件 包含service的配置信息

    kubectl expose deployment web --port=80 --target-port=80 --dry-run -o yaml > service.yaml
    
    • 1

    service.yaml 如下所示

    apiVersion: v1
    kind: Service
    metadata:
      creationTimestamp: null
      labels:
        app: web
      name: web
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        app: web
    status:
      loadBalancer: {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    如果我们没有做设置的话,默认使用的是第一种方式 ClusterIp,也就是只能在集群内部使用,我们可以添加一个type字段,用来设置我们的service类型

    apiVersion: v1
    kind: Service
    metadata:
      creationTimestamp: null
      labels:
        app: web
      name: web
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        app: web
      type: NodePort
    status:
      loadBalancer: {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    修改完命令后,我们使用创建一个pod

    kubectl apply -f service.yaml
    
    • 1

    然后能够看到,已经成功修改为 NodePort类型了,最后剩下的一种方式就是LoadBalanced:对外访问应用使用公有云

    node一般是在内网进行部署,而外网一般是不能访问到的,那么如何访问的呢?

    • 找到一台可以通过外网访问机器,安装nginx,反向代理
    • 手动把可以访问的节点添加到nginx中

    如果我们使用LoadBalancer,就会有负载均衡的控制器,类似于nginx的功能,就不需要自己添加到nginx上

    四层负载均衡 Service:概念、原理解读

    为什么要有 Service?

    在 kubernetes 中,Pod 是有生命周期的,如果 Pod 重启它的 IP 很有可能会发生变化。如果我们的服务都是将 Pod 的 IP 地址写死,Pod 挂掉或者重启,和刚才重启的 pod 相关联的其他服务将会找不到它所关联的 Pod,为了解决这个问题,在 kubernetes 中定义了 service 资源对象,Service 定义了一个服务访问的入口,客户端通过这个入口即可访问服务背后的应用集群实例,service 是一组 Pod 的逻辑集合, 这一组 Pod 能够被 Service 访问到,通常是通过标签选择器实现的。
    请添加图片描述
    1、pod ip 经常变化,service 是 pod 的代理,我们客户端访问,只需要访问 service,就会把请求代理到 Pod

    2、pod ip 在 k8s 集群之外无法访问,所以需要创建 service,这个 service 可以在 k8s 集群外访问 的。

    Service 概述

    service 是一个固定接入层,客户端可以通过访问 service 的 ip 和端口访问到 service 关联的后端 pod,这个 service 工作依赖于在 kubernetes 集群之上部署的一个附件,就是 kubernetes 的 dns 服务 (不同 kubernetes 版本的 dns 默认使用的也是不一样的,1.11 之前的版本使用的是 kubeDNS,较新的版本使用的是 coredns),service 的名称解析是依赖于 dns 附件的,因此在部署完 k8s 之后需要再部署 dns 附件,kubernetes 要想给客户端提供网络功能(比如分配ip),需要依赖第三方的网络插件(flannel,calico 等)。每个 K8s 节点上都有一个组件叫做 kube-proxy,kube-proxy 这个组件将始终监视着 apiserver 中有关 service 资源的变动信息,需要跟 master 之上的 apiserver 交互,随时连接到 apiserver 上获取任何一个与 service 资源相关的资源变动状态,这种是通过 kubernetes 中固有的一种请求方法 watch(监视) 来实现的,一旦有 service 资源的内容发生变动(如创建,删除),然后操作会被存在etcd里,然后会把我们的请求调度到后端特定的 pod 资源之上的规则,这个规则可能是 iptables,也可能是 ipvs,取决于 service 的实现方式(可以自己配置规则)。比如创建了一个新的svc,svc会有一个ip,这个ip的网段是创建集群的时候配置的(默认是10),不过这个ipping不通,是只存在于防火墙规则里的虚拟ip。

    Service 工作原理

    k8s 在创建 Service 时,会根据标签选择器 selector(lable selector)来查找 Pod,据此创建与 Service 同名的 endpoint 对象,当 Pod 地址发生变化时,endpoint 也会随之发生变化,service 接收前端 client 请求的时候,就会通过 endpoint,找到转发到哪个 Pod 进行访问的地址。(至于转发到哪个节点的 Pod,由负载均衡 kube-proxy 决定)

    [root@k8smaster node]# kubectl get endpoints
    NAME         ENDPOINTS             AGE
    kubernetes   192.168.11.139:6443   15d
    [root@k8smaster node]# kubectl get pods -n kube-system -o wide
    NAME                                READY   STATUS    RESTARTS   AGE   IP               NODE     
    kube-apiserver-k8smaster            1/1     Running   4          15d   192.168.11.139   k8smaster 
    apiserver是绑定了宿主机的网络ip,apiserver这个pod,封装的k8sapiservice服务端口是443,这个service关联的pod是apiserver,ednpoints列表里编写的也是apiserverpod的ip和端口
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    kubernetes 集群中有三类 IP 地址

    1、Node Network(节点网络):物理节点或者虚拟节点的网络,如 ens33 接口上的网路地址
    [root@k8smaster node]# ip addr
    ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 00:0c:29:94:59:0f brd ff:ff:ff:ff:ff:ff
        inet 192.168.11.139/24 brd 192.168.11.255 scope global noprefixroute dynamic ens3
    
    2、Pod network(pod 网络),创建的 Pod 具有的 IP 地址 
    [root@k8smaster node]#  kubectl get pods -o wide
    NAME                        READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE  
    frontend-d5tr9              1/1     Running   0          23h   10.244.2.30   k8snode    <none>          
    Node Network 和 Pod network 这两种网络地址是我们实实在在配置的,其中节点网络地址是配置在节点接口之上,而 pod 网络地址是配置在 pod 资源之上的,因此这些地址都是配置在某些设备之上的,这些设备可能是硬件,也可能是软件模拟的 
     
    3、Cluster Network(集群地址,也称为 service network),这个地址是虚拟的地址(virtual ip),没有配置在某个接口上,只是出现在 service 的规则当中。 
    [root@xianchaomaster1 ~]# kubectl get svc 
    [root@k8smaster node]# kubectl get svc
    NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   15d
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    写在最后

    创作不易,如果觉得内容对你有帮助,麻烦给个三连关注支持一下我!如果有错误,请在评论区指出,我会及时更改!
    目前正在更新的系列:从零开始学k8s
    感谢各位的观看,文章掺杂个人理解,如有错误请联系我指出~
    在这里插入图片描述

  • 相关阅读:
    4500亿芯片巨无霸Arm上市!今年最大IPO诞生
    数据结构每日亿题(七)
    【AD】【操作】怎么只选择走线和过孔?(或者是自己选择 要选中的类型)
    4×30m钢筋混凝土简支T梁桥结构设计与计算
    【Unity入门计划】制作RubyAdventure02-处理瓦片地图&碰撞
    为什么需要扩展标签属性?(搭建场景体会)
    C++知识点5:如果一个函数中是if else的结构,在每个条件判断后返回值,和在函数的结尾处返回值有什么区别?
    【Unity3D】摇杆
    企业如何确保电子邮件安全?
    share.weiyun.com 微云无法打开 解决办法
  • 原文地址:https://blog.csdn.net/qq_45400861/article/details/126659678