「Ingress」- 暴露 HTTP and HTTPS 服务 | Kubernetes API Resource

该笔记将记录:与 Ingress 资源有关的内容(但不包含 Ingress Controller 组件部署相关内容),以及常见问题的处理;

认识

文档:https://kubernetes.io/docs/concepts/services-networking/ingress/

Ingress 是个 Kubernetes API 对象,管理外部(集群外部)对内部服务的访问,暴露“从集群外到集群内部服务的” HTTP 与 HTTPS 路由。

补充说明:Ingress is frozen. New features are being added to the Gateway API. 2025-11-18

组成

针对 Ingress 网络 | Understanding kubernetes networking: ingress
Studying the Kubernetes Ingress system

Ingress Controller

Ingress Controller 负责执行 Ingress 资源的定义。

注意,与 Ingress Controller 进行区分

  • Ingress Controller 类似于我们平时作为反向代理的 Nginx 服务,
  • 而 Ingress 则像 Nginx 配置。

Ingress 可以由不同的控制器来实现,通常具有不同的配置。每个 Ingress 应指定一个类,即对 IngressClass 资源的引用,该资源包含其他配置,包括应实现该类的控制器的名称。

性质

  • 通过同个 IP 地址来暴露多个服务
  • 实现基于路径的路由。例如,/api 到后端服务,/static 到前端服务,……
  • 为不同域名配置不同的服务
  • 集中管理 TLS 证书

apiVersion

Deprecated API Migration Guide | Kubernetes

我们见过多种 apiVersion 字段:apiVersion: extensions/v1beta1, apiVersion: networking.k8s.io/v1beta1, apiVersion: networking.k8s.io/v1

针对该现象,其属于正常的 apiVersion 升级,我们根据集群版本进行调整资源声明:

  • 从 v1.22 开始,extensions/v1beta1 与 networking.k8s.io/v1beta1 不再可用;
  • 从 v1.19 开始,networking.k8s.io/v1 可用,并引入很多新的属性字段;

pathType

Each path in an Ingress is required to have a corresponding path type. Paths that do not include an explicit pathType will fail validation.

There are three supported path types:

ImplementationSpecific: With this path type, matching is up to the IngressClass. Implementations can treat this as a separate pathType or treat it identically to Prefix or Exact path types.

Exact: Matches the URL path exactly and with case sensitivity.

Prefix: Matches based on a URL path prefix split by /. Matching is case sensitive and done on a path element by element basis. A path element refers to the list of labels in the path split by the / separator. A request is a match for path p if every p is an element-wise prefix of p of the request path.

ServicePort

ServicePort
在 Ingress 中,能够看到对应关系,ServicePort 对于 Serivce 的 Port 参数;

创建 Ingress 资源

通过命令创建:

kubectl create ingress yearning-ingress –dry-run=client -o yaml –rule=”/=yearning:8000″

kubectl create ingress http-dump –rule=http-dump.example.com/=http-dump:80 –dry-run -o yaml

通过 YAML 文件:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx-example                           # 指定 IngressClass 参数
  rules:
  - http:
      paths:
      - path: /testpath
        pathType: Prefix
        backend:
          service:
            name: test
            port:
              number: 80

创建 HTTPS 的 Ingress 资源 | enable HTTPS

定义 TLS 资源(Secret):

kubectl create secret tls mytlssecret \
  --cert=/path/to/cert/file           \
  --key=/path/to/key/file

# 注意事项:
# --cert must be .PEM encoded (Base64-encoded DER format)
# --key must be in what is commonly called PEM private key format, unencrypted.
# 这两个文件的开始和结尾行都会被忽略;

# 如果需要生成 Secret 资源文件,使用:
kubectl create secret tls mytlssecret               \
  --cert=/path/to/cert/file --key=/path/to/key/file \
  --dry-run=true -o yaml > mytlssecret.yaml

定义并应用部署资源:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-example-ingress
spec:
  tls:
  - hosts:
      - https-example.foo.com
    secretName: mytlssecret
  rules:
  - host: https-example.foo.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: service1
            port:
              number: 80

若存在多个 Ingress Controller 实例,则在 Ingress 中需要添加 Ingress Class 来指定要使用的 Ingress Controler 类型:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example
  namespace: foo
spec:
  ingressClassName: nginx
  rules:
    - host: www.example.com
      http:
        paths:
          - pathType: Prefix
            backend:
              service:
                name: exampleService
                port:
                  number: 80
            path: /
  # This section is only required if TLS is to be enabled for the Ingress
  tls:
    - hosts:
      - www.example.com
      secretName: example-tls

# If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:

apiVersion: v1
kind: Secret
metadata:
  name: example-tls
  namespace: foo
data:
  tls.crt: <base64 encoded cert>
  tls.key: <base64 encoded key>
type: kubernetes.io/tls

创建 TLS 证书

kubectl create secret tls NAME --cert=path/to/cert/file --key=path/to/key/file [--dry-run=server|client|none]

kubectl create secret tls tls-secret --cert=path/to/tls.crt --key=path/to/tls.key

# 更新证书

kubectl create secret tls example-tls --cert=./example.com.pem --key=example.com.key --save-config \
    --dry-run=client -o yaml | kubectl apply -f -

应用

WIP

场景 | 批量处理 Ingress 资源 | Modify Ingresses in Bulk

kubectl Cheat Sheet/Patching Resources
kubectl Cheat Sheet/Kubectl Context and Configuration
How to patch a ConfigMap in Kubernetes
Which is a better and commonly used word, Bulk or Batch?
Developing Custom Oracle Cloud Adapters/Batch and Bulk Operations
Wikipedia/Batch processing

在我们将 Ingress Controller 组件从 Traefik 替换为 Nginx 后,我们迎来壹个新任务 – 替换所有 Ingress 资源中的 kubernetes.io/ingress.class 注解,将其设置为 nginx 参数。

那么多 Ingress 资源肯定要批量替换,而不是挨个手动替换。

Batch and Bulk Operations

  • A bulk operation is a single-target operation that can take a heterogeneous list of business objects.
  • A batch operation includes multiple target operations that each can take a homogeneous or heterogeneous list of business objects.

这就是使用 Batch Processing 词组,而不使用 Bulk Processing 词组的原因。

通过 kubectl patch 命令,批量替换脚本如下:

for ns in $(kubectl get namespaces -o jsonpath='{.items..metadata.name}')
do
    echo "############## NAMESPACE: ${ns} ##############"
    for ingress in $(kubectl get -n $ns ingresses.extensions -o jsonpath='{.items..metadata.name}')
    do
        # 为了防止命令出错,这里只打印将执行的命令,以进行预览
        echo kubectl patch -n $ns ingresses.extensions $ingress --type merge \
            -p \''{"metadata": {"annotations": {"kubernetes.io/ingress.class": "nginx"}}}'\'
    done
done

通过 GeoIP 实现仅允许特定地域访问

DeepSeek / Kubernetes Ingress,如何通过 GeoIP 实现仅允许特定地域访问?

  • 或,使用云商的 WAF 功能。例如 AWS ALB Ingress 可以关联 WAF 规则实现地域限制。
  • 或,使用 Nginx Ingress Controller 的 GeoIP 模块(废弃)
  • 或,使用 Nginx Ingress Controller 的 GeoIP2 模块,并配合 MaxMind GeoIP2 数据库
  • 或,使用其他 Ingress 控制器(例如 Traefik、Kong Ingress Controller、……),其也支持 GeoIP 功能。

参考

kubernetes/CONCEPTS/Ingress
kubernetes/Concepts/Ingress Controllers
k8s1.8 ingress 配置
Sample Ingress resource YAML
NGINX Configuration/Annotations
Basic usage – NGINX Ingress Controller
Secrets | Kubernetes
K8s Ingress 模式简介及示例
Ingress | Kubernetes
Ingress Controllers | Kubernetes
DeepSeek / 介绍 Kubernetes Ingress Controller