理解Kubernetes的网络:Services

什么是Service?

Service 是一个应用服务抽象,定义了 Pod 逻辑集合和访问这个 Pod 集合的策略。

Service提供了一个虚拟的 IP 地址(Cluster IP)和端口号,k8s集群里的任何服务都可以通过Cluster IP+端口的方式来访问此服务,至于访问请求最后会被转发到哪个pod,则由运行在每个node上的kube-proxy 负责。kube-proxy进程其实就是一个智能的软件负载均衡器,负责把对Service的请求转发到后端的某个pod实例上,并在内部实现服务的负载均衡与会话保持机制。

Service 实例

  • [root@k8s-master01 ~]# docker pull daocloud.io/library/tomcat:9.0.22-jdk11-openjdk-slim
    9.0.22-jdk11-openjdk-slim: Pulling from library/tomcat
    1ab2bdfe9778: Pull complete 
    7aaf9a088d61: Pull complete 
    b9283b89acb2: Pull complete 
    16677eca0612: Pull complete 
    9ce560afbba4: Pull complete 
    966cea1f0cfd: Pull complete 
    e3d3da405d9d: Pull complete 
    Digest: sha256:5fd04ca3e001a526415339b1e1398d40bda128d2aecb7e4c74dd408052acfa24
    Status: Downloaded newer image for daocloud.io/library/tomcat:9.0.22-jdk11-openjdk-slim
    
    [root@k8s-master01 ~]# docker run -d -p 18080:8080 --name mytomcat daocloud.io/library/tomcat:9.0.22-jdk11-openjdk-slim
    726060e52f4ed0cebb71a5f5a714535ba7007aab19b66f0522c91a4e4bf212d9
    
    [root@k8s-master01 ~]# docker ps -a|grep tomcat
    726060e52f4e        daocloud.io/library/tomcat:9.0.22-jdk11-openjdk-slim   "catalina.sh run"        About a minute ago   Up About a minute       0.0.0.0:18080->8080/tcp   mytomcat
    
    [root@k8s-master01 ~]# vi deployment-hello.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: frontend
    spec:
      replicas: 1
      selector:
        matchLabels:
          tier: frontend
      template:
        metadata:
          labels:
            app: app-demo
            tier: frontend
        spec:
          containers:
          - name: tomcat-demo
            image: tomcat
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 8080
            resources:
              requests:
                cpu: 0.1
                memory: 300Mi
              limits:
                cpu: 0.5
    
                memory: 320Mi
    ---
    
    apiVersion: v1
    kind: Service
    metadata:
      name: tomcat
      labels:
        name: tomcat1
    spec:
      type: NodePort
      ports:
    
      - port: 80
        targetPort: 8080
        protocol: TCP
        nodePort: 31111
          selector:
        tier: frontend

    多端口为什么需要给每个端口命名呢?这就涉及 Kubernetes 的服务发现机制了。

    Kubernetes 的服务发现机制

每个k8s中的 Service 都有一个唯一的 Cluster IP 及唯一的名字,名字是由我们自己定义的,k8s通过 Add-On 增值包的方式引入了 DNS 系统,把服务名作为 DNS 域名,这样程序就可以直接使用服务名来建立连接了。

端口详解

port

The port that the service is exposed on the service’s cluster ip (virsual ip). Port is the service port which is accessed by others with cluster ip.
这里的port表示:service暴露在cluster ip上的端口,:port 是提供给集群内部客户访问service的入口。

nodePort

On top of having a cluster-internal IP, expose the service on a port on each node of the cluster (the same port on each node). You'll be able to contact the service on any:nodePortaddress. So nodePort is alse the service port which can be accessed by the node ip by others with external ip.
首先,nodePort是kubernetes提供给集群外部客户访问service入口的一种方式(另一种方式是LoadBalancer),所以,nodePort 是提供给集群外部客户访问service的入口。

targetPort

The port on the pod that the service should proxy traffic to.
targetPort很好理解,targetPort是pod上的端口,从port和nodePort上到来的数据最终经过kube-proxy流入到后端pod的targetPort上进入容器。

port、nodePort总结

总的来说,port和nodePort都是service的端口,前者暴露给集群内客户访问服务,后者暴露给集群外客户访问服务。从这两个端口到来的数据都需要经过反向代理kube-proxy流入后端pod的targetPod,从而到达pod上的容器内。

NAME:定义的用户名,DNS就是使用这个域名;
TYPE:NodePort类型;
CLUSTER-IP:分配的集群内IP;
EXTERNAL-IP:针对外部访问集群的IP,NodePort的none意思就是随便一个节点的IP+port;
PORT:80是集群内的映射,31111就是node节点的端口

kube-proxy反向代理

当service有了port和nodePort之后,就可以对内/外提供服务,kube-proxy在本地node上创建的iptables规则。

Kube-Proxy 通过配置 DNAT 规则(从容器出来的访问,从本地主机出来的访问两方面),将到这个服务地址的访问映射到本地的kube-proxy端口(随机端口)。然后 Kube-Proxy 会监听在本地的对应端口,将到这个端口的访问给代理到远端真实的 pod 地址上去。

不管是通过集群内部服务入口:port还是通过集群外部服务入口:nodePort的请求都将重定向到本地kube-proxy端口(随机端口)的映射,然后将到这个kube-proxy端口的访问给代理到远端真实的 pod 地址上去。

上一篇
下一篇