如何暴露Pod中的服务到Kubernetes集群外?

云计算 云原生
在Pod的yaml定义文件中配置该选项后,Pod就使用宿主机的网络栈,这样和直接访问运行在宿主机上的服务没有什么区别。

使用Kubernetes集群运行服务,提供服务的应用运行在Pod中。为了在集群外访问应用,有两类方式:一类是Pod自身实现;其次是依赖其他组件。

  • Pod自身暴露服务

1、hostNetwork:true

在Pod的yaml定义文件中配置该选项后,Pod就使用宿主机的网络栈,这样和直接访问运行在宿主机上的服务没有什么区别,使用“宿主机IP+端口”的方式访问运行在Pod中的服务,比如下面的Pod定义文件,

apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
hostNetwork: true
containers:
- name: nginx
image: nginx:1.23.1
ports:
- containerPort: 80

执行后,登录容器运行的宿主机,可以看到有服务监听在80端口,

监听在宿主机的80端口

访问也是没有问题的(192.168.52.132是宿主机的IP)。

服务访问

如果Pod重启,可能会被调度到别的宿主机,这样的话,访问IP也需跟着变动,还有要防止端口冲突,如果已经有服务占用了宿主机的端口,新的Pod将不能启动。

2、hostPort

将上面Pod的yaml文件稍作修改,增加最后一行,去掉“hostNetwork: true”。

apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.23.1
ports:
- containerPort: 80
hostPort: 8080

相对于第一种,可以灵活地配置对外暴露的端口。有一点需要注意,因为“hostPort”方式,服务监听在容器的网络栈,宿主机在防火墙上做了转发,所以查询宿主机8080端口,发现并没有服务监听,

监听端口

查看防火墙,宿主机做了端口转发。

Pod的IP

宿主机上执行DNAT

这种方式和第一种方式有相同的缺点,容器重启可能会被调度到其他的主机上。不能在一台宿主机上运行同样的Pod,除非人为调整Pod对外暴露的端口。

  • 依赖组件暴露服务

上面两种方法都是依赖Pod自身的资源定义暴露服务到集群外,下面两种方法依赖其他Kubernetes资源实现服务的暴露。

3、NodePort

“NodePort”是Kubernetes中“Service”资源的一个属性,默认“Service”实现集群内服务访问,当增加“NodePort”时,服务便可以在集群外被访问到,Kubernetes默认会从宿主机的端口30000-32767之间选择一个来提供访问,可以人为指定。

一个示例yaml文件。

apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.23.1
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: nginx
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30000
targetPort: 80
selector:
name: nginx

应用该yaml文件后,便可以在集群外通过“主机IP+30000”的方式访问服务。

nodePort方式访问服务

为了实现高可用,可以部署haproxy,后端为多个集群宿主机暴露的服务,这样可以提高可用性。“nodePort”方式的Service工作原理是这样:当流量进入宿主机暴露的30000端口后,会被转发给“Service”的“Cluster IP+端口”,然后通过Iptables(也有可能是ipvs,具体看实现)转发到对应的Pod。

4、Ingress

使用Ingress暴露服务的方式在生产环境中使用的比较多。Ingress API资源对象在kubernetes有内置,但要使用这个对象,需要安装“Controller”。可选的第三方“Controller”有很多,这里选择“Nginx Ingress controller”。(安装过程不涉及)。

示例yaml:

apiVersion: v1
kind: Pod
metadata:
namespace: test
name: nginx
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.23.1
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
namespace: test
name: nginx
spec:
ports:
- port: 8080
targetPort: 80
selector:
name: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: test
name: nginx
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: nginx.example.cc
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: nginx
port:
number: 8080

因为笔者的测试环境Ingress Controller使用nodePort方式运行,对外暴露的HTTP端口为31763。

ingress controller暴露的端口

使用Ingress资源定义中配置的域名访问部署的服务。

访问服务

生产环境可以修改Ingress controller网络的工作方式,比如使用“hostPort”,让其监听在80端口。

有一点需要注意,不同于“nodePort”引导流量到Service的Cluster IP,Ingress Controller会将集群外用户的流量直接送到Pod监听的端口,这样效率会高不少。

总结

除了以上介绍的四种暴露服务的方式,还可以采用“LoadBalancer”,它需要依赖云厂商,如果你的Kubernetes集群部署在公有云上,可以根据实际配置。

责任编辑:姜华 来源: 今日头条
相关推荐

2022-07-07 10:47:16

IngressKubernetes

2022-07-05 08:10:25

Kubernetes云原生

2022-06-27 19:16:12

KubernetesK8s 集群

2023-02-27 07:56:55

IngressKubernetes

2023-11-07 08:23:05

2020-04-10 08:00:08

Kubernetes补丁pod

2023-10-19 19:42:25

IstioPodkubernetes

2023-04-14 14:31:52

Kubernetes服务

2024-06-19 09:33:05

2022-07-18 14:45:22

Kubernetes暴露方案

2021-12-02 08:00:00

Kubernetes集群容器

2022-03-07 10:41:09

云计算容器Kubernetes

2020-11-30 12:15:26

KubernetesPodLinux

2023-03-21 15:26:02

Kubernetes容器开发

2021-11-22 08:00:00

Kubernetes容器集群

2019-11-20 09:15:53

KubernetesPod

2021-12-21 15:17:53

Kubernetes缓存Linux

2023-02-09 16:47:34

KubernetesPod优先级

2024-01-03 10:12:07

Kubernetesdeploymentpod

2022-03-24 07:44:41

OPA安全策略Rego
点赞
收藏

51CTO技术栈公众号