Kubernetes Service

作者: 1092e7c9e0e2 | 来源:发表于2018-09-19 14:18 被阅读297次
    • 什么是Service (服务)
    • 创建一个Service
    • 外部系统访问Service问题
      • 简述NodePort实现方式

    什么是Service (服务)

    图片.png

    Service是Kubernetes里最核心的资源对象之一,Service定义了一个服务的访问入口地址,前端的应用(Pod)通过这个入口地址访问其背后的一组由Pod副本组成的集群实力。 Service与其后端Pod副本集群之间则是通过Label Selector来实现"无缝对接"。而RC的作用实际上是保证Service 的服务能力和服务质量处于预期的标准。

    图片.png

    通过分析、识别并建模系统中所有服务为微服务---Kubernetes Service,最终我们的系统由多个提供不同业务能力而又彼此独立的微服务单元组成,服务之间通过TCP/IP进行通信,从而拥有了强大的分布式能力、弹性扩展能力、容错能力

    既然每个Pod都会被分配一个单独的IP地址,而且每个Pod都提供了一个独立的Endpoint(Pod IP+ContainerPort)以被客户端访问,现在多个Pod副本组成了一个集群来提供访问。

    Kubernetes 需要在每个Node上安装kube-proxy,kube-proxy进程其实就是一个智能的软件负载均衡器,它负责把对Service的请求转发到后端的某个Pod实例上,并在内部实现服务的负载均衡与会话保持机制。

    Kubernetes发明了一个很巧明的设计,Service不是共用一个负载均衡器的IP地址,而是每个Service分配了一个全局唯一的虚拟IP地址,这个虚拟IP被称为Cluster IP。这样每个服务就变成了具备唯一IP地址的"通信节点",服务调用就变成了最基础的TCP网络通信问题

    Pod的Endpoint地址会随着Pod的销毁和重新创建而发生改变,因为新的Pod地址与之前的旧的Pod不同。而Service一旦被创建,Kubernetes就会自动为它分配一个可用的Cluster IP,而且在Service的整个声明周期内,它的Cluster IP不会发生改变。所以只要将Service的name与Service的Cluster IP地址做一个DNS域名映射即可解决问题


    创建一个Service

    案例:手动创建一个Service

    cat > abcdocker-server.yaml <<EOF 
    kind: Service
    apiVersion: v1
    metadata:
      name: mallh5-service
      namespace: abcdocker
    spec:
      selector:
        app: mallh5web
      type: NodePort
      ports:
        - protocol: TCP
          port: 3017
          targetPort: 5003
          nodePort: 31122
    EOF
    
    
    参数 解释
    Port port表示:service暴露在cluster ip(Seriver ip )上的端口,<cluster ip="" style="box-sizing: border-box;">:port 是提供给集群内部客户访问service的入口。</cluster>
    NodePort nodePort是kubernetes提供给集群外部客户访问service入口的一种方式(另一种方式是LoadBalancer,<nodeip style="box-sizing: border-box;">:nodePort 是提供给集群外部客户访问service的入口。</nodeip>
    targetPort targetPort很好理解,targetPort是pod上的端口,从port和nodePort上到来的数据最终经过kube-proxy流入到后端pod的targetPort上进入容器。

    创建

    [root@master test]# kubectl create -f abcdocker-server.yaml
    service/mallh5-service created
    
    

    查看server详细信息

    [root@master test]# kubectl get service --namespace=abcdocker
    NAME             TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
    mallh5-service   NodePort   10.254.22.153   <none>        3017:31122/TCP   13m
    
    [root@master test]# kubectl get service
    NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
    kubernetes      ClusterIP   10.254.0.1       <none>        443/TCP        35d
    nginx-service   NodePort    10.254.200.178   <none>        80:31000/TCP   34d
    
    

    通过kubectl get endpoints可以查看到网络


    外部系统访问Service问题

    我们需要掌握kubernetes中的三种IP

    1.Node IP:Node节点IP地址
    2.Pod IP:Pod的IP地址
    3.Cluster IP:Service的IP地址

    参数解释:
    1.Node IP是Kubernetes集群中每个节点的物理网卡的IP地址,这是一个真实存在的物理网络,所有属于这个网络的服务器之间都能通过这个网络直接通讯,不管他们中间是否含有不属于Kubernetes集群中的节点。想Kubernetes之外的节点访问Kubernetes集群内的节点或者TCP/IP服务时,必须通过Node IP

    图片.png

    2.Pod IP是每个Pod的IP地址,它是Docker Engine 根据docker0网桥的IP地址段进行分配的,通常是一个虚拟的二层网络,Kubernetes要求位于不同Node上的Pod能够彼此直接通讯,所以Kubernetes里一个Pod里的容器访问另外一个Pod里的容器,就是通过Pod IP所在的虚拟二层网络进行通信,而真实的TCP/IP流量则是通过Node IP所在的物理网卡流出

    3.Cluster IP,它是一个虚拟IP,但更像是一个伪造的IP网络

    (1)Cluster IP仅仅作用于Kubernetes Service对象,并由Kubernetes管理和分配IP地址(来源于Cluster IP地址池)
    (2)Cluster IP无法被Ping,因为没有一个"实体网络对象"来影响
    (3)在Kubernetes集群内,Node IP、Pod IP、Cluster IP之间的通信,采用的是Kubernetes自己设计的特殊路由规则

    简述NodePort实现方式

    NodePort的实现方式是在Kubernetes集群里的每个Node上为需要外部访问的Service开启一个对应的TCP请求,外部系统只要用任意Node的IP地址+具体的NodePort端口即可访问服务,在任意node上运行netstat服务,我们可以看到NodePort端口被监听


    image

    但NodePort还没有完全解决外部访问Service的所有问题,比如负载均衡的问题,假如说我们集群中有10个Node,则此时最好有一个负载均衡,外部的请求只需要访问此负载均衡器的IP地址,由负载均衡负责转发流量到后面某个NodePort上


    image

    上图中Load balancer组件独立于Kubernetes集群之外,通常是一个硬件的负载均衡器,或者是以软件方式实现的,例如Haproxy或者Nginx。对于每个Service,我们通常配置一个对应的Load balancer实例来转发流量到后端的Node。

    相关文章

      网友评论

        本文标题:Kubernetes Service

        本文链接:https://www.haomeiwen.com/subject/xwlinftx.html