• 五、K8S之Service


    Kubernetes Service

    一、概念

    Deployment对象部署完应用还需要向外界暴露入口才能通过HTTP访问到K8S集群里的应用Pod。Service就是做这件事情的,为什么还需要一个这样的API对象,一个方面是因为Pod的IP不是固定的,另外一个方面是因为一组Pod实例需要Service提供复杂均衡功能。所以Service是在逻辑抽象层上定义了一组Pod ,为他们提供一个统一的固定IP和访问这组Pod的负载均衡策略

    Service是K8S中非常重要的概念,主要发挥的作用有:

    • 服务发现:Service可以将请求路由到后端Pods,从而实现服务发现的功能。通过Service,应用程序可以从Service的虚拟IP地址或者DNS名称访问一组Pods,并且无需了解实际上的这些Pods的IP地址和端口号
    • 负载均衡:Service在多个Pods质检提供负载均衡服务。当某个Pod无法响应请求时,service会自动将请求重定向到其他可用的Pods中。同时,service还可以根据不同的负载均衡策略(例如轮询、随机等)将请求分配到不同的Pods
    • 稳定的网络访问:Servcie的虚拟IP地址和DNS名称对应的是一组Pod的稳定网络访问**endpoint**。当Pods发生变化(例如,扩容、缩容、重新调度等)时,Service会自动更新Endpoints资源以反映最新的Pods信息。这样,应用程序可以从Service的虚拟IP地址或DNS名称中访问这些Pods,而无需关注它们具体在哪些节点上。
    • 简化配置:Service提供了一种简化配置的方式,可以将多个Pods捆绑在一个逻辑单元中。通过Service,可以对所有后端Pods应用相同的策略(例如标签选择器、负载均衡规则等),从而使配置更加简单和易于管理。

    二、怎么发现Service

    当Service创建时,K8S会自动为该Service分配一个DNS名称,并将该名称与Service关联起来。关联的完整格式为:

    Servcie名称.命名空间.svc.集群域名后缀
    
    • 1

    这个DNS名称很长,有些情况下可以使用简写来替代。同一命名空间中的Pods访问可以省略命名空间,直接使用Service名称就可以访问。如果是在默认的命名空间下,也可以省略,直接使用service名称

    三、Service类型

    对一些应用的某些部分,可能只需要集群内部网路访问,而有些部分(如前端)可能需要其公开外部IP地址,也就是可以从集群外部访问某个地址,所以在创建Service可以指定所需要的Service类型。可用的type有:

    2.1、ClusterIP

    这是默认的Service类型,会将Service对象通过一个内部IP暴露给集群内部,这种类型的Service只能够在集群内部使用和访问,不对外暴露

    2.2、NodePort

    会在每个宿主节点的一个指定固定端口号上暴露Service,与此同时还会自动创建一个ClusterIP类型的Service,NodePort类型的Service会将集群外部的请求路由给NodePort类型的Service。当类型设置为 NodePort 后,可以在 ports 配置中增加 nodePort 配置指定端口,需要在下方的端口范围内,如果不指定会随机指定端口,端口范围:30000~32767

    也可以修改端口范围配置,在文件 /usr/lib/systemd/system/kube-apiserver.servic调整

    2.3、LoadBalancer

    适用于公有云上的Kubernetes服务,使用LoadBalancer类型的Service,同时会自动创建NodePortClusterIP类型的ServiceLoadBalancer会把请求路由到NodePortClusterIP类型的Service上。

    2.4、ExternalName

    ExternalName 类型的 Service,是在 kube-dns 里添加了一条 CNAME 记录。这个CNAME记录是在Service的spec.externalName里指定的,

    以上四种类型除了ExternalNameKuberneteskube-proxy组件都会为Service提供VIP(虚拟IP)

    四、使用

    4.1、ClusterIP类型使用
    • 创建一个一个nginx-service-ClusterIP.yaml文件,内容如下:
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-svc-cluster   # Service名称
      labels:
        app: nginx-svc-cluster # Service标签
    spec:
      type: ClusterIP # service类型
      selector: #匹配哪些pod会被Serivce代理
        app: nginx-deploy
      ports: #端口映射
        - name: http #为这个端口映射起一个名字
          #  端口绑定的协议,支持 TCP、UDP、SCTP,默认为 TCP
          protocol: TCP
          # svc 自己的端口,虚拟
          port: 80
          #  目标 pod 的端口
          targetPort: 90
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 查看service创建情况

      
      kubectl get svc
      
      -------------------------------------------------
      NAME                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                     AGE
      kubernetes          ClusterIP   10.96.0.1       <none>        443/TCP                     20d
      nginx-svc-cluster   ClusterIP   10.110.228.98   <none>        80/TCP                      16m
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    • 访问

      • 创建一个创建busybox的Pod

      前面说过ClusterIP类型只能供集群内网访问,所以我们只能先创建一个pod,进去这个pod,再来访问这个地址

      # 创建busyboxpod
      kubectl run busybox-pod --image=busybox --restart=Always 
      
      #进进入容器
      kubectl exec -it busybox-pod -- sh
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 访问

        wget 10.110.228.98
        或者
        wget nginx-svc-cluster
        
        • 1
        • 2
        • 3
    4.2、NodePort类型使用
    
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-svc-nodeport
      labels:
        app: nginx-svc-nodeport
    spec:
      type: NodePort
      selector: #匹配哪些pod会被Serivce代理
        app: nginx-deploy
      ports: #端口映射
        - name: http #为这个端口映射起一个名字
          #  端口绑定的协议,支持 TCP、UDP、SCTP,默认为 TCP
          protocol: TCP
          # nodePort是svc占用宿主机的一个端口
          # nodePort: 30080
          # svc 自己的端口,虚拟
          port: 80
          #  目标 pod 的端口
          targetPort: 90
        - name: http2
          port: 81
          targetPort: 91
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    查看service创建情况

    kubectl get svc
    
    -------------------------------------------------
    NAME                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                     AGE
    kubernetes          ClusterIP   10.96.0.1       <none>        443/TCP                     20d
    nginx-svc-nodeport  NodePort    10.98.195.178   <none>        80:31216/TCP,81:30517/TCP   39h
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这里创建一个名叫nginx-svc 类型为NodePort的service,并且绑定了两个端口号,如果绑定两个端口号则访问的时候加上对应的端口号,如:

    # 这样就能访问到pod的90端口号
    wget nginx-svc-nodePort:80
    
    
    # 这样就能访问到pod的91端口号
    wget nginx-svc-nodePort:81
    
    --不需要再容器中使用
    # 这样就能访问到pod的90端口号
    wget 192.168.31.100:31216
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    4.3、ExternalName类型使用
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-svc-externalname   # Service名称
      labels:
        app: nginx-svc-externalname # Service标签
    spec:
      type: ExternalName
      externalName: www.baidu.com
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    进去容器测试

    # 进入容器
    kubectl exec -it busybox-pod -- sh
    
    #测试
    ping nginx-svc-externalnam
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    图神经推荐系统笔记整理
    MySQL读写分离
    java,mqtt-client开发创建客户端
    采购实验室信息管理系统的意义及其应用价值
    Kamailio 的 uuid_kill
    天星金融普及个人养老金制度,共筑老龄友好型社会
    订单超时未支付自动取消8种实现方案
    解析vue.config.js文件
    防火墙相关知识整理
    Termux配置bashrc,终端长路径改为短路径
  • 原文地址:https://blog.csdn.net/qq_39381892/article/details/133849030