Kubernetes 之Ingress 从基础到实战全解析
一、Ingress 核心概念
1.Ingress是什么?
- 本质:管理外部 HTTP/HTTPS 流量访问集群内服务的 API 资源对象(七层路由),但不是k8s核心组件的组成部分,在k8s中是可选的,通常以pod形式部署。
- 作用:提供负载均衡、SSL/TLS 终止、基于名称的虚拟主机等。
- 类比: 集群的“智能路由器”或“门户守卫”,根据规则(主机名、路径)将请求分发给不同的后端 Service。
2.为什么需要Ingress?
Service
(NodePort/LoadBalancer) 主要解决四层 (TCP/UDP) 访问,缺乏应用层(HTTP)的路由能力(如按域名、路径转发),而Ingress刚好解决了这一点。- 避免为每个微服务创建昂贵的云负载均衡器。
-
集中管理外部访问入口和安全策略(如 TLS)。
3.Ingress核心组件
Ingress
资源 (Resource):定义路由规则的 YAML 文件(声明期望状态)。- Ingress 控制器 (Controller): Ingress Controller 是 Kubernetes 官方设计模式下的标准扩展组件, 实际执行规则的Pod。负责监听
Ingress
资源变化,配置底层的负载均衡器(如 Nginx, Envoy, HAProxy, 云厂商的 LB)或代理来实现规则。Ingress 资源本身不工作,必须配合控制器!
4. Ingress VS Service
特性 | Ingress | Service |
工作层 | 应用层 (L7 - HTTP/HTTPS) | 传输层 (L4 - TCP/UDP/SCTP) |
路由能力 | 基于主机名、路径、Header | 仅基于端口和 ClusterIP |
协议 | HTTP, HTTPS, gRPC (部分) | 任意 TCP/UDP |
实现 | 依赖独立的 Ingress 控制器 | kube-proxy (iptables/IPVS) 或云 LB |
主要目的 | 外部 HTTP(S) 流量入口管理 | 集群内部服务发现与负载均衡,暴露端口 |
二、部署Nginx Ingress Controller
1.通过 kubectl 直接部署
1.1 下载官方yaml文件
#下载文件
[root@master-1 ingress]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.0/deploy/static/provider/cloud/deploy.yaml
1.2 修改关键配置
#修改部署 YAML 中的 image 字段
registry.aliyuncs.com/google_containers/nginx-ingress-controller:v1.10.0
registry.aliyuncs.com/google_containers/kube-webhook-certgen:v1.4.0#修改service类型
# type: LoadBalancertype: NodePort
1.3 部署
[root@master-1 ingress]# cat nginx-deploy.yaml
apiVersion: v1
kind: Namespace
metadata:labels:app.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxname: ingress-nginx
---
apiVersion: v1
automountServiceAccountToken: true
kind: ServiceAccount
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginxnamespace: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx-admissionnamespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginxnamespace: ingress-nginx
rules:
- apiGroups:- ""resources:- namespacesverbs:- get
- apiGroups:- ""resources:- configmaps- pods- secrets- endpointsverbs:- get- list- watch
- apiGroups:- ""resources:- servicesverbs:- get- list- watch
- apiGroups:- networking.k8s.ioresources:- ingressesverbs:- get- list- watch
- apiGroups:- networking.k8s.ioresources:- ingresses/statusverbs:- update
- apiGroups:- networking.k8s.ioresources:- ingressclassesverbs:- get- list- watch
- apiGroups:- coordination.k8s.ioresourceNames:- ingress-nginx-leaderresources:- leasesverbs:- get- update
- apiGroups:- coordination.k8s.ioresources:- leasesverbs:- create
- apiGroups:- ""resources:- eventsverbs:- create- patch
- apiGroups:- discovery.k8s.ioresources:- endpointslicesverbs:- list- watch- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx-admissionnamespace: ingress-nginx
rules:
- apiGroups:- ""resources:- secretsverbs:- get- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:labels:app.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx
rules:
- apiGroups:- ""resources:- configmaps- endpoints- nodes- pods- secrets- namespacesverbs:- list- watch
- apiGroups:- coordination.k8s.ioresources:- leasesverbs:- list- watch
- apiGroups:- ""resources:- nodesverbs:- get
- apiGroups:- ""resources:- servicesverbs:- get- list- watch
- apiGroups:- networking.k8s.ioresources:- ingressesverbs:- get- list- watch
- apiGroups:- ""resources:- eventsverbs:- create- patch
- apiGroups:- networking.k8s.ioresources:- ingresses/statusverbs:- update
- apiGroups:- networking.k8s.ioresources:- ingressclassesverbs:- get- list- watch
- apiGroups:- discovery.k8s.ioresources:- endpointslicesverbs:- list- watch- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx-admission
rules:
- apiGroups:- admissionregistration.k8s.ioresources:- validatingwebhookconfigurationsverbs:- get- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginxnamespace: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: ingress-nginx
subjects:
- kind: ServiceAccountname: ingress-nginxnamespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx-admissionnamespace: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: ingress-nginx-admission
subjects:
- kind: ServiceAccountname: ingress-nginx-admissionnamespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:labels:app.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: ingress-nginx
subjects:
- kind: ServiceAccountname: ingress-nginxnamespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx-admission
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: ingress-nginx-admission
subjects:
- kind: ServiceAccountname: ingress-nginx-admissionnamespace: ingress-nginx
---
apiVersion: v1
data:allow-snippet-annotations: "false"
kind: ConfigMap
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx-controllernamespace: ingress-nginx
---
apiVersion: v1
kind: Service
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx-controllernamespace: ingress-nginx
spec:externalTrafficPolicy: LocalipFamilies:- IPv4ipFamilyPolicy: SingleStackports:- appProtocol: httpname: httpport: 80protocol: TCPtargetPort: http- appProtocol: httpsname: httpsport: 443protocol: TCPtargetPort: httpsselector:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxtype: NodePort
---
apiVersion: v1
kind: Service
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx-controller-admissionnamespace: ingress-nginx
spec:ports:- appProtocol: httpsname: https-webhookport: 443targetPort: webhookselector:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxtype: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx-controllernamespace: ingress-nginx
spec:minReadySeconds: 0revisionHistoryLimit: 10selector:matchLabels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxstrategy:rollingUpdate:maxUnavailable: 1type: RollingUpdatetemplate:metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0spec:containers:- args:- /nginx-ingress-controller- --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller- --election-id=ingress-nginx-leader- --controller-class=k8s.io/ingress-nginx- --ingress-class=nginx- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller- --validating-webhook=:8443- --validating-webhook-certificate=/usr/local/certificates/cert- --validating-webhook-key=/usr/local/certificates/key- --enable-metrics=falseenv:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: LD_PRELOADvalue: /usr/local/lib/libmimalloc.soimage: registry.aliyuncs.com/google_containers/nginx-ingress-controller:v1.10.0imagePullPolicy: IfNotPresentlifecycle:preStop:exec:command:- /wait-shutdownlivenessProbe:failureThreshold: 5httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10successThreshold: 1timeoutSeconds: 1name: controllerports:- containerPort: 80name: httpprotocol: TCP- containerPort: 443name: httpsprotocol: TCP- containerPort: 8443name: webhookprotocol: TCPreadinessProbe:failureThreshold: 3httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10successThreshold: 1timeoutSeconds: 1resources:requests:cpu: 100mmemory: 90MisecurityContext:allowPrivilegeEscalation: falsecapabilities:add:- NET_BIND_SERVICEdrop:- ALLreadOnlyRootFilesystem: falserunAsNonRoot: truerunAsUser: 101seccompProfile:type: RuntimeDefaultvolumeMounts:- mountPath: /usr/local/certificates/name: webhook-certreadOnly: truednsPolicy: ClusterFirstnodeSelector:kubernetes.io/os: linuxserviceAccountName: ingress-nginxterminationGracePeriodSeconds: 300volumes:- name: webhook-certsecret:secretName: ingress-nginx-admission
---
apiVersion: batch/v1
kind: Job
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx-admission-createnamespace: ingress-nginx
spec:template:metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx-admission-createspec:containers:- args:- create- --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc- --namespace=$(POD_NAMESPACE)- --secret-name=ingress-nginx-admissionenv:- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespaceimage: registry.aliyuncs.com/google_containers/kube-webhook-certgen:v1.4.0imagePullPolicy: IfNotPresentname: createsecurityContext:allowPrivilegeEscalation: falsecapabilities:drop:- ALLreadOnlyRootFilesystem: truerunAsNonRoot: truerunAsUser: 65532seccompProfile:type: RuntimeDefaultnodeSelector:kubernetes.io/os: linuxrestartPolicy: OnFailureserviceAccountName: ingress-nginx-admission
---
apiVersion: batch/v1
kind: Job
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx-admission-patchnamespace: ingress-nginx
spec:template:metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx-admission-patchspec:containers:- args:- patch- --webhook-name=ingress-nginx-admission- --namespace=$(POD_NAMESPACE)- --patch-mutating=false- --secret-name=ingress-nginx-admission- --patch-failure-policy=Failenv:- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespaceimage: registry.aliyuncs.com/google_containers/kube-webhook-certgen:v1.4.0imagePullPolicy: IfNotPresentname: patchsecurityContext:allowPrivilegeEscalation: falsecapabilities:drop:- ALLreadOnlyRootFilesystem: truerunAsNonRoot: truerunAsUser: 65532seccompProfile:type: RuntimeDefaultnodeSelector:kubernetes.io/os: linuxrestartPolicy: OnFailureserviceAccountName: ingress-nginx-admission
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: nginx
spec:controller: k8s.io/ingress-nginx
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.10.0name: ingress-nginx-admission
webhooks:
- admissionReviewVersions:- v1clientConfig:service:name: ingress-nginx-controller-admissionnamespace: ingress-nginxpath: /networking/v1/ingressesfailurePolicy: FailmatchPolicy: Equivalentname: validate.nginx.ingress.kubernetes.iorules:- apiGroups:- networking.k8s.ioapiVersions:- v1operations:- CREATE- UPDATEresources:- ingressessideEffects: None[root@master-1 ingress]# kubectl apply -f nginx-deploy.yaml
1.4 验证
2.通过 Helm 部署(推荐生产环境)
2.1 添加更新仓库
# 添加仓库 & 更新
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
2.2 拉取代码
[root@master-1 ingress]# helm pull ingress-nginx/ingress-nginx#内网环境可直接从外网下载
https://github.com/kubernetes/ingress-nginx/releases/download/helm-chart-4.12.3/ingress-nginx-4.12.3.tgz
2.3 修改关键配置
[root@master-1 ingress]# cd /root/ingress/ingress-nginx[root@master-1 ingress-nginx]# vim values.yaml global:image:# -- Registry host to pull images from.registry: registry.aliyuncs.comcontroller:image:# registry: registry.k8s.ioimage: google_containers/nginx-ingress-controller## repository:tag: "v1.10.0"admissionWebhooks:patch:image:# registry: registry.k8s.ioimage: google_containers/kube-webhook-certgen## repository:tag: v1.4.0service:type: NodePort
2.4 部署
[root@master-1 ingress-nginx]# cd ../
#部署ingress-nginx
[root@master-1 ingress]# helm install ingress-nginx ingress-nginx -n ingress-nginx --create-namespace -f ingress-nginx/values.yaml#查看
[root@master-1 ingress]# helm list -n ingress-nginx
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
ingress-nginx ingress-nginx 1 2025-07-01 14:42:20.362166146 +0800 CST deployed ingress-nginx-4.12.3 1.12.3
2.5 验证
2.6 补充helm常用命令
helm详细教程尽情期待下一章节
#搜索ingress-nginx
[root@master-1 ingress]# helm search repo ingress-nginx
NAME CHART VERSION APP VERSION DESCRIPTION
ingress-nginx/ingress-nginx 4.12.3 1.12.3 Ingress controller for Kubernetes using NGINX a...# 下载ingress-nginx
[root@master-1 ingress]# helm pull ingress-nginx/ingress-nginx#安装 ingress-nginx ingress-nginx 第一个是为ingress服务取名称为ingress-nginx,第二个是目录名
[root@master-1 ingress]# helm install ingress-nginx ingress-nginx -n ingress-nginx --create-namespace -f ingress-nginx/values.yaml#卸载 ingress-ngin
[root@master-1 ingress]# helm uninstall ingress-nginx -n ingress-nginx
三、配置ingress路由规则
1.部署nginx应用通过nginx.liux.com访问
1.1 部署nginx
[root@master-1 ~]# cat nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx
spec:replicas: 3#基于标签关联pod,会关联env=test或者env=prod的podselector:matchExpressions:- key: envvalues: - "test"- "prod"operator: Intemplate:metadata:#为pod设置了两个标签labels:app: nginxenv: testspec:# 基于节点的标签进行调度,将Pod调度到包含key为type,value为ssd的节点上。nodeSelector:app: testcontainers:- name: nginximage: nginx:latestimagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:name: nginx-service
spec:# 指定svc的类型为NodePort,也就是在默认的ClusterIP基础之上多监听所有worker节点的端口而已。type: NodePort# 基于标签选择器关联Podselector:app: nginx# 配置端口映射ports:# 指定Service服务本身的端口号- port: 8888# 后端Pod提供服务的端口号targetPort: 80# 如果是NodePort类型,可以指定NodePort监听的端口号,若不指定,则随机生成。nodePort: 30080#端口范围以上提供了查询方法,可以修改,修改api-server启动时的参数.#nodePort: 8080
1.2 创建 Ingress 规则
[root@master-1 ~]# cat nginx-route.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress-routeannotations:nginx.ingress.kubernetes.io/rewrite-target: /
spec:ingressClassName: nginxrules:- host: nginx.liux.comhttp:paths:- path: /pathType: Prefixbackend:service:name: nginx-serviceport:number: 80[root@master-1 ~]# kubectl apply -f nginx-route.yaml
1.3 测试访问
#本地配置hosts
192.168.91.21 nginx.liux.com
#页面访问 显示nginx页面
http://nginx.liux.com/