k8s 之如何从集群外部访问内部服务的三种方法

本文主要整理一下学习和实践过程中,外部如何访问集群内部服务的三种方法,记录一下实践的过程和理解。

1. k8s集群中三种IP(NodeIP、PodIP、ClusterIP)介绍

1.1 三种 IP 定义

  • NodeIP:Node 节点的 IP 地址,即物理机(虚拟机)的 IP 地址。
  • PodIP:Pod 的 IP 地址,即 docker 容器的 IP 地址,此为虚拟 IP 地址。
  • ClusterIP:k8s 虚拟的 Service 的 IP 地址,此为虚拟 IP 地址。

1.2 三种 IP 的理解

  • Node IP:
    是物理机的IP(或虚拟机IP)。每个Service都会在Node节点上开通一个端口,外部可以通过 http://NodeIP:NodePort 即可访问 Service 里的 Pod 提供的服务。
  • Pod IP:
    是每个 Pod 的 IP 地址,Docker Engine根据 docker 网桥的 IP 地址段进行分配的,通常是一个虚拟的二层网络。
    • 同Service下的pod可以直接根据PodIP相互通信
    • 不同Service下的pod在集群间pod通信要借助于 cluster ip
    • pod和集群外通信,要借助于node ip
  • Cluster IP
    是 Service 的 IP 地址,此为虚拟 IP 地址,外部网络无法 ping 通,只有kubernetes集群内部访问使用。
    • Cluster IP仅仅作用于Kubernetes Service这个对象,并由Kubernetes管理和分配P地址 Cluster
    • IP无法被ping,他没有一个“实体网络对象”来响应 Cluster IP只能结合Service
    • Port组成一个具体的通信端口,单独的Cluster IP不具备通信的基础,并且他们属于Kubernetes集群这样一个封闭的空间。
    • 在不同Service下的pod节点在集群间相互访问可以通过Cluster IP

1.3 三种 IP 关系图

k8s 之如何从集群外部访问内部服务的三种方法_第1张图片
①:代表外部通过公有云的 LoadBalancer 负载均衡服务访问集群内部服务流程
②:代表外部用户直接访问集群内部 Service 的 ClusterIP 访问集群内部服务流程
③:代表集群内部不同 Service 之间的 Pod 服务访问流程
④:代表集群内部同一个 Service 中 Pod 服务之间访问流程

2. 客户端如何从外部访问集群内部的服务

那么 Pod 和 Service 都是 k8s 集群内部范围的虚拟概念,所以集群外部客户端无法通过 Pod 的 IP 地址或者 Service 的虚拟 IP 地址和虚机端口号访问他们。
那集群外部客户端如何访问内部服务呢?

第一种方法:
将 Pod 或 Service 的端口号映射到宿主机,以使客户端应用能够通过物理机访问容器应用。

第二种方法:
通过公有云的 LoadBalancer 服务负载均衡,以使客户端从外部访问集群内部容器应用。

第三种方法(推荐):
使用 k8s 自带的 Ingress 负载均衡服务,以使客户端从外部访问集群内部容器应用。

2.1 (第一种方法)将容器应用的端口直接映射到物理机

2.1.1 将 Pod 容器的端口直接映射到宿主机(不推荐)

  • webapp-pod-hostPort.yaml
apiVersion: v1
kind: Pod
metadata:
  name: webapp 
  labels:
    app: webapp 
spec:
  # hostNetwork: true  		# 网络模式选择为使用宿主机网络,即容器所有的端口都会自动映射到宿主机上
  containers:
  - name: webapp
    image: tomat
    ports:
    - containerPort: 8080	# 容器的运行端口为 8080
      hostPort: 8081 		# 映射到宿主机的端口为 8081,如果上边设置了网络模式,则不需要加 hostPort
  • (不推荐)此种方法比较直接,客户端直接访问指定的容器服务。即客户端通过宿主机的 8081 端口即可访问容器服务, curl :8081 。但是这样的方式只能访问指定单一的容器服务,没有负载均衡,所以不推荐。

2.1.2 将 Service 的端口映射到物理机

  • webapp-service-nodePort.yaml
apiVersion: v1
kind: Service 
metadata: 
  name: webapp 
spec: 
  type: NodePort		# 设置 Service 类型为 NodePort
  ports: 
  - port: 8080 			# 设置 Service 暴露的端口为 8080, 即8080(svc) <-> 80(pod)
    targetPort: 80		# 设置 Pod 的端口为 8080
    nodePort: 30081 	# 设置 NodePort 的端口为 30081,即30081(NodePort) <-> 8080(svc) <-> 80(Pod) 
  selector:
    app: webapp 
  • Service 包含一组相关的容器,一起来提供服务。
  • 将 Service 的端口映射到物理机的端口上,k8s会在每个工作节点上做端口映射,实现负载均衡服务,访问 curl :30081,NodeIP 可以是集群中任意一个Node节点。
  • 如果有 Haproxy 负载均衡服务,ClusterIP + Haproxy 为推荐方式

2.2 (第二种方法)通过 LoadBalancer 访问集群内部容器服务

待完善 …

2.3(第三种方法)通过 Ingress 访问集群内部容器服务

待完善 …

  • 2.3(第三种方法)通过 Ingress 访问集群内部容器服务

    待完善 …

posted @ 2021-08-19 11:03  技术颜良  阅读(5304)  评论(0编辑  收藏  举报