1、ingress简要介绍
ingress和service之间的区别
我们在前面的模块中已经介绍了基于service的四层的对外访问,ingress也是一种对外访问的服务,那么这两者之间有什么区别呢。
在Kubernetes集群中,Service和Ingress是两种不同层次的流量管理组件。Service主要负责集群内部的服务发现和负载均衡,它基于标签选择器将请求转发到后端Pod,并提供稳定的IP地址(ClusterIP)或NodePort供内部访问。而Ingress则是更高级的流量入口,它工作在应用层(L7),可以根据URL路径、域名等规则将外部请求分发到不同的Service,实现路径路由、域名虚拟主机等功能。Ingress本身并不直接处理流量,而是通过配置规则由Ingress Controller(如Nginx、Traefik)来实现具体转发逻辑。
换句话说,ingress工作在第七层,service工作在第四层,两者虽是同样的服务类型,但是提供的服务并不一样
2 、ingress对外暴露服务的三种方式
2.1 deployment+loadbanancer
Deployment是用于管理Pod的部署和副本数量的资源对象,它确保应用程序的多个实例(Pod)按照定义的规格运行在集群中。而LoadBalancer类型的Service则是在Deployment的基础上,通过与云服务提供商或底层基础设施进行交互,自动创建一个外部负载均衡器。当创建一个LoadBalancer类型的Service时,Kubernetes会向相关的云平台或基础设施请求分配一个公网IP地址,并将该IP地址与Service关联起来。这个外部负载均衡器会将外部客户端发送到该公网IP的流量,根据配置的规则转发到后端由Deployment管理的Pod上。这样,外部用户就可以通过这个公网IP来访问部署在Kubernetes集群中的应用服务。这种方式相对简单直接,不需要像Ingress那样依赖额外的Ingress控制器来实现复杂的路由和流量管理功能,适用于一些对流量路由规则要求不高,只需要简单地将服务暴露到外部网络的场景。它能快速地将服务部署并对外提供访问,利用云平台的负载均衡能力实现流量的分发和负载均衡,保障应用的高可用性和性能。但它在功能上相对Ingress较为有限,例如无法像Ingress那样基于HTTP的路径或域名进行精细的流量路由控制。
把ingress部署在公有云,可以采用这种方式,loadBanancer会为service自动创建一个负载均衡器,只要域名解析指向到loadbalancer的地址,就可以实现集群的的对外访问
2.2 daemonSET+hostNnetwork+nodeselector
DaemonSet确保在集群中的每个节点或匹配特定条件的节点上都运行一个Pod副本。使用HostNetwork意味着Pod将直接使用节点的网络命名空间,绕过了Kubernetes的网络隔离,使得Pod可以直接使用节点的IP地址和端口,这样外部请求可以直接访问到节点上运行的服务,就好像服务直接运行在节点上一样。而NodeSelector则用于指定DaemonSet中的Pod应该被调度到哪些具有特定标签的节点上,通过这种方式可以控制服务在哪些节点上对外暴露。这种方式的优点是简单直接,不需要额外的负载均衡器或复杂的网络配置,能够快速地将服务部署到指定的节点并使其可被外部访问。同时,由于Pod直接使用节点网络,避免了一些网络地址转换和代理带来的性能损耗。然而,这种方式也有一些局限性,它可能会导致节点上的端口资源竞争,因为多个Pod可能会使用相同的端口,而且缺乏像Ingress那样的高级流量管理功能,如基于路径或域名的路由、SSL/TLS终止等。此外,它对集群的网络安全配置也有一定影响,因为绕过了Kubernetes的网络隔离,需要更加谨慎地管理节点的网络访问权限。
ingress-controller会直接使用宿主机的网络和端口,一个node节点能部署一个ingress-controller的pod,适用于大并发的生产环境
2.3 deployment+Nodeport
在Kubernetes中,“Deployment + NodePort”是一种常用的将服务暴露到集群外部的方式,但严格来说它并非传统的Ingress。Deployment用于管理应用程序的部署,它通过定义Pod模板来创建和管理多个Pod副本,确保应用能够以期望的状态运行在集群中。而NodePort类型的Service则是在Deployment的基础上,为服务提供了一种通过节点IP和指定端口来访问服务的方式。当创建一个NodePort类型的Service时,Kubernetes会在每个节点上分配一个固定的端口(在30000 - 32767范围内),并将发往该端口的流量转发到后端由Deployment管理的Pod上。这样,外部客户端就可以通过访问集群中任意节点的IP地址加上这个指定的NodePort来访问到部署在集群中的服务。这种方式的优点是简单易懂且易于配置,不需要依赖外部的负载均衡器或复杂的Ingress控制器。它能够快速地将服务暴露到集群外部,适用于一些简单的应用场景,尤其是在开发、测试环境或者小型集群中,能够方便地让外部用户访问到集群内的服务。然而,它也存在一些局限性,例如每个节点上的端口资源有限,可能会导致端口冲突;而且这种方式没有提供像Ingress那样基于域名、路径等更细粒度的流量路由和管理功能,对于复杂的应用架构和多样化的流量需求难以满足。同时,直接暴露节点端口可能会带来一定的安全风险,需要在网络安全方面进行额外的配置和管理。
deployment部署也会执行一个ingress-controller的pod,pod也会对应一个service,service 的模式是Nodeport,分别对应http的80和https的443
3、详细介绍
3.1 deployment+loadbanancer
适用场景多为服务器的公有云,我们主要介绍后面两种类型的ingress服务
3.2 daemonSET+hostNnetwork+nodeselector
指定nginx-ingress-controller 运行在 node02 节点
kubectl label node node02 ingress=true
kubectl get nodes --show-labels
修改 Deployment 为 DaemonSet ,指定节点运行,并开启 hostNetwork 网络
vim mandatory.yaml
...
apiVersion: apps/v1
# 修改 kind
# kind: Deployment
kind: DaemonSet
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
# 删除Replicas
# replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
spec:
# 使用主机网络
hostNetwork: true
# 选择节点运行
nodeSelector:
ingress: "true"
serviceAccountName: nginx-ingress-serviceaccount
......
在所有 node 节点上传 nginx-ingress-controller 镜像压缩包ingree.contro.tar.gz 到 /opt/ingress 目录,并解压和加载镜像
cd /opt/ingress
tar -xf ingree.contro-0.30.0.tar.gz
docker load -i ingree.contro-0.30.0.tar
启动 nginx-ingress-controller
kubectl apply -f mandatory.yaml
在node02节点上查看端口监听情况
创建 ingress 规则
创建一个 deploy 和 svc
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc1
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client-storageclass
resources:
requests:
storage: 2Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-app1
labels:
app: nginx1
spec:
replicas: 3
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
containers:
- name: nginx1
image: nginx:1.22
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- name: nfs-pvc
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: nfs-pvc1
---
apiVersion: v1
kind: Service
metadata:
name: nginx-app-svc1
spec:
type: ClusterIP
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
app: nginx1
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-app-ingress1
spec:
rules:
- host: www.benet.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-app-svc1
port:
number: 80
应用
kubectl apply -f service-nginx.yaml
在 nfs master 上配置node2映射
在nfs服务器上往最新的pvc中输入一串特殊字符
用浏览器访问–成功
3.3 deployment+Nodeport
删除之前挂载的记录,方便后续的实验
把控制器改成deployment注释掉相关的字段
应用
配置service-nodeport
vim service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
- name: https
port: 443
targetPort: 443
protocol: TCP
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
应用
测试
kubectl get svc -n ingress-nginx
– 获取端口号
4、在windows上访问
我们先要改一下windows的hosts文件
路径:C:\Windows\System32\drivers\etc 事后最好要改回来,不然可能会出小问题
然后就可以访问了