k8s对外服务之ingress使用详解

 更新时间:2025年07月10日 09:22:33   作者:新是一切的根源  
Ingress作为K8s的7层负载均衡器,通过单一入口管理多个服务,使用IngressController(如Nginx)和资源,支持按域名/路径路由,解决端口冲突与配置复杂问题

1. ingress概述

k8s 对外暴露服务(service)主要有两种方式:NotePort, LoadBalance, 此外externalIPs也可以使各类service对外提供服务,但是当集群服务很多的时候,NodePort方式最大的缺点是会占用很多集群机器的端口;LB方式最大的缺点则是每个service一个LB又有点浪费和麻烦,并且需要k8s之外的支持; 而ingress则只需要一个NodePort或者一个LB就可以满足所有service对外服务的需求。

工作机制大致可以用下图表示:

实际上,ingress相当于一个7层的负载均衡器,是k8s对反向代理的一个抽象。大概的工作原理也确实类似于Nginx,可以理解成在 Ingress 里建立一个个映射规则 , ingress Controller 通过监听 Ingress这个api对象里的配置规则并转化成 Nginx 的配置(kubernetes声明式API和控制循环) , 然后对外部提供服务。

ingress包括:ingress controller和ingress resources

  • ingress controller:核心是一个deployment,实现方式有很多,比如nginx, Contour, Haproxy, trafik, Istio,需要编写的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中service的类型可以是NodePort或者LoadBalancer。
  • ingress resources:这个就是一个类型为Ingress的k8s api对象了,这部分则是面向开发人员。

Kubernetes给出的方案就是Ingress,Ingress包含了两大主件Ingress Controller和Ingress。

Ingress解决的是新的服务加入后,域名和服务的对应问题,基本上是一个ingress的对象,通过yaml进行创建和更新进行加载。

Ingress Controller是将Ingress这种变化生成一段Nginx的配置,然后将这个配置通过Kubernetes API写到Nginx的Pod中,然后reload.(注意:写入 nginx.conf 的不是service的地址,而是service backend 的 pod 的地址,避免在 service 在增加一层负载均衡转发)

从上图中可以很清晰的看到,实际上请求进来还是被负载均衡器拦截,比如 nginx,然后 Ingress Controller 通过跟 Ingress 交互得知某个域名对应哪个 service,再通过跟 kubernetes API 交互得知 service 地址等信息;综合以后生成配置文件实时写入负载均衡器,然后负载均衡器 reload 该规则便可实现服务发现,即动态映射

了解了以上内容以后,这也就很好的说明了我为什么喜欢把负载均衡器部署为 Daemon Set;因为无论如何请求首先是被负载均衡器拦截的,所以在每个 node 上都部署一下,同时 hostport 方式监听 80 端口;那么就解决了其他方式部署不确定 负载均衡器在哪的问题,同时访问每个 node 的 80 都能正确解析请求;如果前端再 放个 nginx 就又实现了一层负载均衡。

Ingress Controller 会根据你定义的 Ingress 对象,提供对应的代理能力。业界常用的各种反向代理项目,比如 Nginx、HAProxy、Envoy、Traefik 等,都已经为Kubernetes 专门维护了对应的 Ingress Controller。

2. ingress-nginx 部署

ingress调度的是后端的service,而不是pod

ingress controller 是与k8s集群做交互的,感知etcd的变化

首先拉取 ingress-controller镜像至harbor仓库

部署nginx-ingress-controller

拿到yaml文件 应用ingress controller定义文件

[kubeadm@server1 ingress]$ ls
mandatory.yaml
[kubeadm@server1 ingress]$ 

编辑此文件,把镜像的位置换成本地仓库中镜像的位置

应用ingress controller定义文件


应用ingress-service定义文件

查看信息


3. 创建ingress服务

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-demo
spec:
  backend:
    serviceName: nginx-svc
    servicePort: 80
创建 service.yaml文件
kind: Service
apiVersion: v1
metadata:
  name: nginx-svc
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: nginx
[kubeadm@server1 ingress]$ \vi ingress.yaml
[kubeadm@server1 ingress]$ vim ingress.yaml 
[kubeadm@server1 ingress]$ vim service.yaml
[kubeadm@server1 ingress]$ kubectl apply -f service.yaml 
service/myservice created
[kubeadm@server1 ingress]$ kubectl apply -f ingress.yaml 
ingress.networking.k8s.io/ingress-demo created
[kubeadm@server1 ingress]$ 

ingress-nginx调度nginx-svc这个服务

[kubeadm@server1 ingress]$ kubectl -n ingress-nginx get svc
NAME            TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.99.32.59   <none>        80:30016/TCP,443:31941/TCP   31m
[kubeadm@server1 ingress]$ 

外部访问

实现myservice服务中的负载均衡,因为ingress-nginx也是通过nodeport模式的端口暴露,实现外部访问

4. 通过域名的形式来访问后端

5. 通过不同的域名定义到不同的后端

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-myapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: reg.westos.org/k8s/myapp:v2
        ports:
        - containerPort: 80


---
kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: myapp
  type: ClusterIP

---

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-example
spec:
  rules:
  - host: www2.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: myservice
          servicePort: 80


[kubeadm@server1 ingress]$ kubectl get ingress
NAME              CLASS    HOSTS             ADDRESS       PORTS   AGE
ingress-demo      <none>   www1.westos.org   10.99.32.59   80      36m
ingress-example   <none>   www2.westos.org   10.99.32.59   80      3m22s
[kubeadm@server1 ingress]$ 

访问www2.westos.org时访问到v2

访问www1.westos.org时访问到v1

访问不同的域名,访问到的后端service不同,负载到不同的pod后端

6. 访问同一域名,不同的path时,调度到不同的后端

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-hello
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: www3.westos.org 
    http:
      paths:
      - path: /1 
        backend:
          serviceName: ingress-nginx
          servicePort: 80 
      paths:
      - path: /2
        backend:
          serviceName: myservice
          servicePort: 80


总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • K8S中设置JVM堆栈大小实现方式

    K8S中设置JVM堆栈大小实现方式

    这篇文章主要介绍了K8S中设置JVM堆栈大小实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-07-07
  • Kubernetes访问控制之鉴权方法详解

    Kubernetes访问控制之鉴权方法详解

    这篇文章主要为大家介绍了Kubernetes访问控制之鉴权方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 解决K8S中Node状态为NotReady的步骤

    解决K8S中Node状态为NotReady的步骤

    在Kubernetes集群中,Node状态为NotReady通常意味着节点上存在某些问题,解决Node节点NotReady状态的步骤包括检查节点日志、容器运行时状态、网络组件、节点资源、节点与控制平面的通信,本文介绍解决K8S中Node状态为NotReady的步骤,感兴趣的朋友一起看看吧
    2025-03-03
  • Jenkins打包、发布、部署完整骤记录

    Jenkins打包、发布、部署完整骤记录

    这篇文章主要介绍了Jenkins的基本概念,服务器环境检查,以及如何安装和配置Jenkins,包括安装FTP服务、Maven、Git和Jenkins本身,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-03-03
  • k8s中如何实现pod自动扩缩容详解

    k8s中如何实现pod自动扩缩容详解

    在实际生产系统中,经常会遇到某个服务需要扩容的场景,可能会遇到由于资源紧张或者工作负载降低而需要减少服务实例数量的场景,下面这篇文章主要给大家介绍了关于k8s中如何实现pod自动扩缩容的相关资料,需要的朋友可以参考下
    2022-08-08
  • 云原生系列Kubernetes深度解析YAML文件使用

    云原生系列Kubernetes深度解析YAML文件使用

    这篇文章主要为大家介绍了云原生系列Kubernetes深度解析YAML文件使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • Rainbond网络治理插件ServiceMesh官方文档说明

    Rainbond网络治理插件ServiceMesh官方文档说明

    这篇文章主要为大家介绍了Rainbond网络治理插件ServiceMesh官方文档说明,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-04-04
  • Centos 8.2 升级内核通过elrepo源的方法

    Centos 8.2 升级内核通过elrepo源的方法

    这篇文章主要介绍了Centos 8.2 升级内核通过elrepo源,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10
  • Kubernetes如何限制不同团队只能访问各自namespace实现

    Kubernetes如何限制不同团队只能访问各自namespace实现

    这篇文章主要为大家介绍了Kubernetes如何限制不同团队只能访问各自namespace实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • K8S 中 kubectl 命令详解

    K8S 中 kubectl 命令详解

    这篇文章主要介绍了K8S 中 kubectl 命令,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07

最新评论