Ingress 七层路由机制

1. Ingress 基本概念

Ingress 是 Kubernetes 中用于管理外部访问集群内服务的 API 对象,它提供了一种 基于 HTTP/HTTPS 路由规则 的流量管理方式,Ingress 与 Service 对比如下:

特性IngressService (NodePort/LoadBalancer)
协议支持HTTP/HTTPSTCP/UDP
路由规则基于域名/路径基于 IP + 端口
适用场景Web 应用(如 Nginx、Apache)非 HTTP 服务(如数据库、gRPC)
依赖组件需要 Ingress Controller内置(kube-proxy)

Ingress 核心组件

  • Ingress Resource:定义路由规则(如 example.com/app1 → service1:80)。
  • Ingress Controller:实际处理流量的代理(如 Nginx、Traefik、HAProxy)。
  • Service:后端 Pod 的访问入口(ClusterIP 或 NodePort)。

2. Ingress 使用示例

2.1. 部署 Ingress Controller

Ingress Controller 需要实现基于不同 HTTP URL 向后转发的负载分发规则,并可以灵活设置七层负载分发策略。目前 Ingress Controller 已经有许多实现方案,包括 Nginx、 HAProxy、Kong、Traefik、Skipper、Istio 等开源软件的实现,以及公有云 GCE、Azure、 AWS 等提供的 Ingress应用网关,用户可以参考官方网站根据业务需求选择适合的 Ingress Controller。下面示例使用 Nginx 提供的 Ingress Controller。

Ingress Controller 对外暴露服务的几种方式:

  • 将 Ingress Controller 容器的端口映射到宿主机上,通过宿主机的 IP + 端口访问,这种方式只能通过 Ingress Controller pod 所在的节点 IP + 端口访问,需要设置节点亲和,使 Ingress Controller pod 固定在一个节点上。
  • Ingress Controller pod 使用 hostNetwork 网络模式直接监听宿主机的 IP 和端口,同样也只能通过 Ingress Controller pod 所在的节点 IP + 端口访问。
  • 为 Ingress Controller 创建 NodePort Service,将端口映射到宿主机,这种方式可以通过集群任意节点的 IP + 端口访问。
  • 云环境可以使用 LoadBalancer Service 对外暴露服务。

官方部署 yaml 文件:

# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.1/deploy/static/provider/cloud/deploy.yaml

apiVersion: v1
kind: Namespace
metadata:
  labels:
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  name: ingress-nginx
---
apiVersion: v1
automountServiceAccountToken: true
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx
  namespace: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx-admission
  namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx
  namespace: ingress-nginx
rules:
- apiGroups:
  - ""
  resources:
  - namespaces
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - configmaps
  - pods
  - secrets
  - endpoints
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - services
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses/status
  verbs:
  - update
- apiGroups:
  - networking.k8s.io
  resources:
  - ingressclasses
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - coordination.k8s.io
  resourceNames:
  - ingress-nginx-leader
  resources:
  - leases
  verbs:
  - get
  - update
- apiGroups:
  - coordination.k8s.io
  resources:
  - leases
  verbs:
  - create
- apiGroups:
  - ""
  resources:
  - events
  verbs:
  - create
  - patch
- apiGroups:
  - discovery.k8s.io
  resources:
  - endpointslices
  verbs:
  - list
  - watch
  - get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx-admission
  namespace: ingress-nginx
rules:
- apiGroups:
  - ""
  resources:
  - secrets
  verbs:
  - get
  - create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx
rules:
- apiGroups:
  - ""
  resources:
  - configmaps
  - endpoints
  - nodes
  - pods
  - secrets
  - namespaces
  verbs:
  - list
  - watch
- apiGroups:
  - coordination.k8s.io
  resources:
  - leases
  verbs:
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - services
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - events
  verbs:
  - create
  - patch
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses/status
  verbs:
  - update
- apiGroups:
  - networking.k8s.io
  resources:
  - ingressclasses
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - discovery.k8s.io
  resources:
  - endpointslices
  verbs:
  - list
  - watch
  - get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx-admission
rules:
- apiGroups:
  - admissionregistration.k8s.io
  resources:
  - validatingwebhookconfigurations
  verbs:
  - get
  - update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx
  namespace: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: ingress-nginx
subjects:
- kind: ServiceAccount
  name: ingress-nginx
  namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx-admission
  namespace: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: ingress-nginx-admission
subjects:
- kind: ServiceAccount
  name: ingress-nginx-admission
  namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: ingress-nginx
subjects:
- kind: ServiceAccount
  name: ingress-nginx
  namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx-admission
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: ingress-nginx-admission
subjects:
- kind: ServiceAccount
  name: ingress-nginx-admission
  namespace: ingress-nginx
---
apiVersion: v1
data:
  allow-snippet-annotations: "false"
kind: ConfigMap
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx-controller
  namespace: ingress-nginx
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  #externalTrafficPolicy: Local
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - appProtocol: http
    name: http
    port: 80
    protocol: TCP
    targetPort: http
  - appProtocol: https
    name: https
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  type: NodePort  # 修改
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx-controller-admission
  namespace: ingress-nginx
spec:
  ports:
  - appProtocol: https
    name: https-webhook
    port: 443
    targetPort: webhook
  selector:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  minReadySeconds: 0
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app.kubernetes.io/component: controller
      app.kubernetes.io/instance: ingress-nginx
      app.kubernetes.io/name: ingress-nginx
  strategy:
    rollingUpdate:
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app.kubernetes.io/component: controller
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
        app.kubernetes.io/version: 1.10.1
    spec:
      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=false
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: LD_PRELOAD
          value: /usr/local/lib/libmimalloc.so
        image: registry.k8s.io/ingress-nginx/controller:v1.10.1@sha256:e24f39d3eed6bcc239a56f20098878845f62baa34b9f2be2fd2c38ce9fb0f29e  # 按需修改镜像地址
        imagePullPolicy: IfNotPresent
        lifecycle:
          preStop:
            exec:
              command:
              - /wait-shutdown
        livenessProbe:
          failureThreshold: 5
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        name: controller
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        - containerPort: 443
          name: https
          protocol: TCP
        - containerPort: 8443
          name: webhook
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources:
          requests:
            cpu: 100m
            memory: 90Mi
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            add:
            - NET_BIND_SERVICE
            drop:
            - ALL
          readOnlyRootFilesystem: false
          runAsNonRoot: true
          runAsUser: 101
          seccompProfile:
            type: RuntimeDefault
        volumeMounts:
        - mountPath: /usr/local/certificates/
          name: webhook-cert
          readOnly: true
      dnsPolicy: ClusterFirst
      nodeSelector:
        kubernetes.io/os: linux
      serviceAccountName: ingress-nginx
      terminationGracePeriodSeconds: 300
      volumes:
      - name: webhook-cert
        secret:
          secretName: ingress-nginx-admission
---
apiVersion: batch/v1
kind: Job
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx-admission-create
  namespace: ingress-nginx
spec:
  template:
    metadata:
      labels:
        app.kubernetes.io/component: admission-webhook
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
        app.kubernetes.io/version: 1.10.1
      name: ingress-nginx-admission-create
    spec:
      containers:
      - args:
        - create
        - --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc
        - --namespace=$(POD_NAMESPACE)
        - --secret-name=ingress-nginx-admission
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.1@sha256:36d05b4077fb8e3d13663702fa337f124675ba8667cbd949c03a8e8ea6fa4366  # 按需修改镜像地址
        imagePullPolicy: IfNotPresent
        name: create
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
            - ALL
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          runAsUser: 65532
          seccompProfile:
            type: RuntimeDefault
      nodeSelector:
        kubernetes.io/os: linux
      restartPolicy: OnFailure
      serviceAccountName: ingress-nginx-admission
---
apiVersion: batch/v1
kind: Job
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx-admission-patch
  namespace: ingress-nginx
spec:
  template:
    metadata:
      labels:
        app.kubernetes.io/component: admission-webhook
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
        app.kubernetes.io/version: 1.10.1
      name: ingress-nginx-admission-patch
    spec:
      containers:
      - args:
        - patch
        - --webhook-name=ingress-nginx-admission
        - --namespace=$(POD_NAMESPACE)
        - --patch-mutating=false
        - --secret-name=ingress-nginx-admission
        - --patch-failure-policy=Fail
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.1@sha256:36d05b4077fb8e3d13663702fa337f124675ba8667cbd949c03a8e8ea6fa4366  # 按需修改镜像地址
        imagePullPolicy: IfNotPresent
        name: patch
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
            - ALL
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          runAsUser: 65532
          seccompProfile:
            type: RuntimeDefault
      nodeSelector:
        kubernetes.io/os: linux
      restartPolicy: OnFailure
      serviceAccountName: ingress-nginx-admission
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: nginx
spec:
  controller: k8s.io/ingress-nginx
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  labels:
    app.kubernetes.io/component: admission-webhook
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: ingress-nginx-admission
webhooks:
- admissionReviewVersions:
  - v1
  clientConfig:
    service:
      name: ingress-nginx-controller-admission
      namespace: ingress-nginx
      path: /networking/v1/ingresses
  failurePolicy: Fail
  matchPolicy: Equivalent
  name: validate.nginx.ingress.kubernetes.io
  rules:
  - apiGroups:
    - networking.k8s.io
    apiVersions:
    - v1
    operations:
    - CREATE
    - UPDATE
    resources:
    - ingresses
  sideEffects: None
YAML

部署:

# 部署
kubectl apply -f deploy.yaml
Bash

访问 Nginx Ingress Controller:

kubectl -n ingress-nginx get svc ingress-nginx-controller
NAME                       TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller   NodePort   10.102.137.2   <none>        80:31695/TCP,443:30147/TCP   33s


curl 192.168.2.151:31695
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

# Nginx Ingress Controller 没有配置后端服务会返回 404
Bash

2.2. 创建 Ingress 策略

配置 Ingress 策略前需要保证后端服务正常运行,后端服务示例如下:

# gowebhost-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: gowebhost
  name: gowebhost
spec: 
  replicas: 2
  selector: 
    matchLabels:
      app: gowebhost     
  strategy: {}
  template:                
    metadata:
      labels:
        app: gowebhost
    spec:                  
      containers:
      - image: nginx:1.26.2
        name: nginx
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: gowebhost
  name: gowebhost
spec:
  ports:
  - port: 9999
    protocol: TCP
    targetPort: 80
  selector:
    app: gowebhost
  type: ClusterIP
YAML
# gowebip-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: gowebip
  name: gowebip
spec: 
  replicas: 2
  selector: 
    matchLabels:
      app: gowebip     
  strategy: {}
  template:                
    metadata:
      labels:
        app: gowebip
    spec:                  
      containers:
      - image: nginx:1.26.2
        name: nginx
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: gowebip
  name: gowebip
spec:
  ports:
  - port: 8888
    protocol: TCP
    targetPort: 80
  selector:
    app: gowebip
  type: ClusterIP
YAML

部署:

kubectl apply -f gowebhost-svc.yaml
kubectl apply -f gowebip-svc.yaml
Bash

Ingress yaml 文件:

# ingress-test1.yaml
apiVersion: networking.k8s.io/v1 
kind: Ingress
metadata:
  name: ingress-test
  namespace: default
  annotations:
    #kubernetes.io/ingress.class: "nginx"
    # 重写路径:将 /ip/xxx 截取为 /xxx
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    # 开启 use-regex,启用 path 的正则匹配 
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  ingressClassName: nginx
  rules:
    # 定义域名
    - host: test.ingress.com
      http:
        paths:
          # 不同 path 转发到不同端口
          - path: /ip(/|$)(.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: gowebip
                port: 
                  number: 8888
          - path: /host(/|$)(.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: gowebhost
                port: 
                  number: 9999
YAML

创建 Ingress 资源对象:

kubectl apply -f ingress-test1.yaml
Bash

创建 Ingress 资源后,Ingress Controller 就会监控到,并将其更新到 nginx 的配置文件中。

# 进入 Ingress Controller pod 
kubectl -n ingress-nginx exec -it ingress-nginx-controller-6bb485db4b-d85dr -- bash

# 查看
cat /etc/nginx/nginx.conf | grep "test.ingress.com" -A 10
	
	## start server test.ingress.com
	server {
		server_name test.ingress.com ;
		
		http2 on;
		
		listen 80  ;
		listen [::]:80  ;
		listen 443  ssl;
		listen [::]:443  ssl;
		
		set $proxy_upstream_name "-";
		
--
	## end server test.ingress.com
	
	# backend for when default-backend-service is not configured or it does not have endpoints
	server {
		listen 8181 default_server reuseport backlog=4096;
		listen [::]:8181 default_server reuseport backlog=4096;
		set $proxy_upstream_name "internal";
		
		access_log off;
		
		location / {
...
Bash

2.3. 客户端通过 Ingress Controller 访问后端服务

curl -H 'Host:test.ingress.com' http://192.168.2.151:31695/host

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
# 成功访问到后端 nginx 服务
Bash

3. Ingress 资源对象详解

Ingress 资源主要用于定义路由转发规则。示例如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /  # 常用注解
spec:
  ingressClassName: nginx  # 指定 Ingress Controller
  tls:
  - hosts:
    - example.com
    secretName: example-tls  # TLS 证书 Secret
  rules:
  - host: example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
      - path: /static
        pathType: Exact
        backend:
          service:
            name: static-service
            port:
              number: 8080
YAML

3.1. Annotations 注解

在 ingress 配置中,annotations 很重要,可以用来控制启用何种功能。

常用注解

注解作用示例
nginx.ingress.kubernetes.io/rewrite-target路径重写rewrite-target: /$2
nginx.ingress.kubernetes.io/use-regex启用正则use-regex: “true”
nginx.ingress.kubernetes.io/ssl-redirectHTTP 跳转 HTTPSssl-redirect: “true”

3.2. Rules 规则

  • host:域名匹配,空则匹配所有域名。
  • http.paths:一组根据路径进行转发的规则设置,每个路径都应配置相应的后端服务信息(服务名称和服务端口号)。只有客户端请求中的 host 和 path 都匹配之后,才会进行转发。
  • http.paths.pathType:路径匹配方式。
    • Prefix:前缀匹配。
    • Exact:精确匹配。
    • ImplementationSpecific:由 Controller 实现,通常用于正则匹配。
  • http.paths.backend:目标后端服务,包括服务的名称和端口号。

如果一个请求同时被 Ingress 中设置的多条 URL 路径匹配,则系统将优先选择最长的匹配路径。如果有两条同等长度的匹配路径,则精确匹配类型(Exact 类型)优先于前缀匹配类型(Prefix 类型)。

后端通常被设置为目标服务,另外可以为不匹配任何路由规则的请求设置一个默认的后端(defaultBackend)。在未设置 defaultBackend 时,如何处理与所有规则(rule) 都不匹配的流量,将由 Ingress Controller 决定。

3.3. ingressClassName 和 ingressClass

在一个 k8s 集群中可以部署多个不同类型的 Ingress Controller 提供服务,此时需要在 Ingress 资源上注明该策略由哪一个 Controller 管理。

部署 Ingress Controller 时指定控制器标识

# Ingress Controller Deployment 示例片段
spec:
  template:
    spec:
      containers:
      - name: controller
        args:
          - /nginx-ingress-controller
          - --controller-class=k8s.io/ingress-nginx  # 必须与 IngressClass 的 controller 字段匹配
YAML

IngressClass 绑定到特定的 Ingress Controller:

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.10.1
  name: nginx    # IngressClass 名字
spec:
  controller: k8s.io/ingress-nginx  # 绑定字段
YAML

Ingress 资源指定 IngressClass

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  ingressClassName: nginx  # 对应 IngressClass.metadata.name
YAML

注意:Ingress 和 IngressClass 作用范围都是整个 k8s 集群,可以跨名称空间。

默认 IngressClass 设置:

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: nginx
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"  # 添加注解设置为默认IngressClass
spec:
  controller: nginx.org/ingress-controller
  
# 设置了默认 IngressClass 后,如果 Ingress 资源没有显示指定 IngressClass,则使用默认 IngressClass。
YAML

3.4. TLS 安全配置

生成证书 Secret

# 命令行直接创建
kubectl create secret tls example-tls --cert=./tls.crt --key=./tls.key
Bash

在 Ingress 中引用

tls:
- hosts:
  - example.com
  secretName: example-tls
YAML
上一篇
下一篇