Kubernetes 的外部访问方式

前言

我们知道在 K8s 集群内部,由于 pod 的不可靠性引入了 service 的概念,将提供相同服务若干副本的 pod 通过标签创建一个 service ,集群内部通过访问该 service 通过 Endpoint 负载均衡到 pod 来实现服务请求。

那么 K8s 如何提供外部访问方式呢?

NodePort

每个集群节点都会在节点上打开一个端口,并将在端口上接受到的流量重定向到基础服务,可以通过所有节点的专用端口访问。

如图,可以通过所有 Node 的该 Port 访问
在这里插入图片描述

使用

创建一个服务并将其类型设置为 NodePort,通过创建 NodePort 服务,可以让 K8s 在所有节点上保留一个端口,将传入的连接转发给服务部分的 pod。

apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport
spec:
  type: NodePort			# 类型 NodePort
  ports:
  - port: 80					# Pod 端口
    targetPort: 8080		# ClusterIP Port
    nodePort: 30080		# 外部访问 NodePort,不写会随机
  selector:
    app: nginx2

LoadBalancer

LoadBalancer 本质上来说是 NodePort 的扩展,通常需要在支持自动提供负载均衡器的云基础架构上运行。

在这里插入图片描述

使用

创建服务后,通过 external-ip 来提供访问服务。

apiVersion: v1
kind: Service
metadata:
  name: nginx-lb
spec:
  type: LoadBalancer			# 类型 LoadBalancer
  ports:
  - port: 80					# Pod 端口
    targetPort: 80			# ClusterIP Port
  selector:
    app: nginx2

Ingress

引入 Ingress 的一个重要原因是每个 LoadBalancer 服务都需要自己的负载均衡器,以及独立的公有 IP 地址,而 Ingress 只需要一个公网 IP 就可以为许多服务提供访问。当客户端向 Ingress 发送 HTTP 请求时,Ingress 会根据请求的主机名和路径决定请求转发到的服务;

要想 Ingress 资源正常工作,必须要有 Ingress 控制器在集群中运行,可以选择不同的 Ingress 控制器,如:Nginx/Envoy/Treafik/Kong,或一些公有云提供的服务。

在这里插入图片描述

使用

功能迭代较快,下面提供 k8s 版本 v1.17.2,使用 nginx 作为 ingress-controller

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: test-ingress-1
  annotations: 
    nginx.ingress.kubernetes.io/rewrite-target: /   # (1)
spec:
  rules:
  - host: test.example.com		# (2)
    http:
      paths:
      - path: /foo		# (3)
        backend:
          serviceName: nginx-service		# (4)
          servicePort: 80
      - path: /bar
        backend:
          serviceName: nginx-service2
          servicePort: 80

(1) nginx 作为 controller 时需要的注解,路径匹配说明详情见https://kubernetes.io/zh/docs/concepts/services-networking/ingress/
(2) 访问的主机名
(3) 路径
(4) 对应的服务
创建 Ingress 资源,当访问 test.example.com/foo 时,转到 nginx-service 服务,且端口为 80;当访问 test.example.com/bar 时,转到 nginx-service2 服务,且端口为 80.

*k8s v18 后,需要多加入 pathType 选项,如 Prefix,Exact。

Port Forward

除了上述几种提供外部访问 pod 的方式,额外描述一种在调试时快速访问 pod 的方法:

通过 kubectl port-forward 命令,它可以在本机上开启一个转发端口,间接转发到 K8s 内部的某个 Pod 的端口上。这种方式是TCP转发,不限于HTTP。

kubectl port-forward test2-nginx 8888:80 --address 0.0.0.0 (绑定到0.0.0.0)
Logo

开源、云原生的融合云平台

更多推荐