【问题标题】:How to set up a custom HTTP error in Kubernetes如何在 Kubernetes 中设置自定义 HTTP 错误
【发布时间】:2020-05-21 14:58:01
【问题描述】:

我想创建一个自定义 403 错误页面。 目前我已经创建了一个入口,并且在注释中我有这样的内容:

"nginx.ingress.kubernetes.io/whitelist-source-range": "100.01.128.0/20,88.100.01.01"

因此,任何在该 IP 范围之外访问我的网络应用程序的尝试都会收到 403 错误。

为了创建自定义页面,我尝试添加以下注释:

"nginx.ingress.kubernetes.io/custom-http-errors": "403",
"nginx.ingress.kubernetes.io/default-backend": "default-http-backend"

其中 default-http-backend 是已部署应用的名称。

入口有这个:

{
  "kind": "Ingress",
  "apiVersion": "extensions/v1beta1",
  "metadata": {
    "name": "my-app-ingress",
    "namespace": "my-app-test",
    "selfLink": "/apis/extensions/v1beta1/namespaces/my-app-test/ingresses/my-app-ingress",
    "uid": "8f31f2b4-428d-11ea-b15a-ee0dcf00d5a8",
    "resourceVersion": "129105581",
    "generation": 3,
    "creationTimestamp": "2020-01-29T11:50:34Z",
    "annotations": {
      "kubernetes.io/ingress.class": "nginx",
      "nginx.ingress.kubernetes.io/custom-http-errors": "403",
      "nginx.ingress.kubernetes.io/default-backend": "default-http-backend",
      "nginx.ingress.kubernetes.io/rewrite-target": "/",
      "nginx.ingress.kubernetes.io/whitelist-source-range": "100.01.128.0/20,90.108.01.012"
    }
  },
  "spec": {
    "tls": [
      {
        "hosts": [
          "my-app-test.retail-azure.js-devops.co.uk"
        ],
        "secretName": "ssl-secret"
      }
    ],
    "rules": [
      {
        "host": "my-app-test.retail-azure.js-devops.co.uk",
        "http": {
          "paths": [
            {
              "path": "/api",
              "backend": {
                "serviceName": "my-app-backend",
                "servicePort": 80
              }
            },
            {
              "path": "/",
              "backend": {
                "serviceName": "my-app-frontend",
                "servicePort": 80
              }
            }
          ]
        }
      }
    ]
  },
  "status": {
    "loadBalancer": {
      "ingress": [
        {}
      ]
    }
  }
}

但我总是得到默认的 403。 我错过了什么?

【问题讨论】:

  • 我在这里试过你的配置,一切都很好。您的服务“my-app-frontend”、“default-http-backend”和入口在同一个命名空间中?
  • 它们都在同一个前端,但是当我从非白名单 IP 访问我的网络应用程序时,我没有看到“default-http-backend”...(我仍然看到真正的默认值一)。我不知道它是如何为您工作或为什么...可能是因为我将“default-http-backend”用作服务名称...这可能是一个冲突
  • 你能描述一下服务 default-http-backend 吗?您还可以提供您想要作为默认后端的 pod 的 ips 吗?

标签: kubernetes kubernetes-ingress


【解决方案1】:

我想创建一个自定义 403 错误页面。目前我已经在注释中创建了一个入口。 因此,任何在该 IP 范围之外访问我的 Web 应用程序的尝试都会收到 403 错误。 为了创建自定义页面,我尝试添加以下注释:

kind: Ingress
metadata:
  name: my-app-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: "/"
    nginx.ingress.kubernetes.io/custom-http-errors: '403'
    nginx.ingress.kubernetes.io/default-backend: default-http-backend
    nginx.ingress.kubernetes.io/whitelist-source-range: 125.10.156.36/32
spec:
  rules:
  - host: venkat.dev.vboffice.com
    http:
      paths:
      - path: "/"
        backend:
          serviceName: custom-http-backend
          servicePort: 80

其中 default-http-backend 是已经使用默认 nginx 页面部署的应用的名称。

如果我使用白名单 IP 在家进行测试,则会显示自定义页面,但如果我尝试在 4G 网络中使用手机访问,则会显示默认后端 404

我需要添加任何 nginx 配置更改 custom-http-backend pod????

部署一:default-http-backend

apiVersion: apps/v1
kind: Deployment
metadata:
  name: default-http-backend
spec:
  selector:
    matchLabels:
      app: default-http-backend
  template:
    metadata:
      labels:
        app: default-http-backend
    spec:
      containers:
      - name: default-http-backend
        image: nginx
        ports:
        - name: http
          containerPort: 80
        imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
  name: default-http-backend
spec:
  selector:
    app: default-http-backend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

部署2:custom-http-backend

apiVersion: apps/v1
kind: Deployment
metadata:
  name: custom-http-backend
spec:
  selector:
    matchLabels:
      app: custom-http-backend
  template:
    metadata:
      labels:
        app: custom-http-backend
    spec:
      containers:
      - name: custom-http-backend
        image: inanimate/echo-server
        ports:
        - name: http
          containerPort: 8080
        imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
  name: custom-http-backend
spec:
  selector:
    app: custom-http-backend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

【讨论】:

    【解决方案2】:

    我已经复制了你的场景,这对我有用。 我将尝试按照我所遵循的步骤指导您。

    云提供商:GKE Kubernetes 版本:v1.15.3 命名空间default

    我正在使用 2 个映像的 2 个部署,每个部署一个服务。

    服务 1default-http-backend - 使用 nginx 映像,它将是我们的默认后端。

    服务 2custom-http-backend - 带有 inanimate/echo-server 图像,如果请求来自列入白名单的 ip,将显示此服务。

    入口:带有注释的 Nginx 入口。

    预期行为: Ingress 将被配置为使用 default-backendcustom-http-errorswhitelist-source-range 注释。如果请求来自白名单 IP,入口将重定向到 custom-http-backend,否则将重定向到 default-http-backend

    部署一:default-http-backend

    用这个内容创建一个文件default-http-backend.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: default-http-backend
    spec:
      selector:
        matchLabels:
          app: default-http-backend
      template:
        metadata:
          labels:
            app: default-http-backend
        spec:
          containers:
          - name: default-http-backend
            image: nginx
            ports:
            - name: http
              containerPort: 80
            imagePullPolicy: IfNotPresent
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: default-http-backend
    spec:
      selector:
        app: default-http-backend
      ports:
        - protocol: TCP
          port: 80
          targetPort: 80
    

    应用yaml文件:k apply -f default-http-backend.yaml

    部署2:custom-http-backend

    使用此内容创建一个文件custom-http-backend.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: custom-http-backend
    spec:
      selector:
        matchLabels:
          app: custom-http-backend
      template:
        metadata:
          labels:
            app: custom-http-backend
        spec:
          containers:
          - name: custom-http-backend
            image: inanimate/echo-server
            ports:
            - name: http
              containerPort: 8080
            imagePullPolicy: IfNotPresent
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: custom-http-backend
    spec:
      selector:
        app: custom-http-backend
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
    

    应用yaml文件:k apply -f custom-http-backend.yaml

    检查服务是否启动并运行

    我将别名 k 用于 kubectl

    ➜  ~ k get svc                                 
    NAME                   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
    custom-http-backend    ClusterIP   10.125.5.227   <none>        80/TCP    73s
    default-http-backend   ClusterIP   10.125.9.218   <none>        80/TCP    5m41s
    ...
    
    ➜  ~ k get pods
    NAME                                    READY   STATUS    RESTARTS   AGE
    custom-http-backend-67844fb65d-k2mwl    1/1     Running   0          2m10s
    default-http-backend-5485f569bd-fkd6f   1/1     Running   0          6m39s
    ...
    

    您可以使用port-forward 测试服务:

    默认-http-后端 k port-forward svc/default-http-backend 8080:80 尝试在浏览器中访问http://localhost:8080 以查看 nginx 默认页面。

    自定义http后端 k port-forward svc/custom-http-backend 8080:80 尝试在浏览器中访问http://localhost:8080 以查看 echo-server 图像提供的自定义页面。

    入口配置

    此时我们已经启动并运行了两个服务,我们需要安装和配置 nginx 入口。可以关注official documentation,这里不再赘述。

    安装后让我们部署入口,根据您发布的代码我做了一些修改:tls 删除,添加其他域并删除路径 /api 仅用于测试目的,并将我的家庭 IP 添加到白名单。

    使用内容创建一个文件my-app-ingress.yaml

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: my-app-ingress
      namespace: default
      annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/rewrite-target: "/"
        nginx.ingress.kubernetes.io/custom-http-errors: '403'
        nginx.ingress.kubernetes.io/default-backend: default-http-backend
        nginx.ingress.kubernetes.io/whitelist-source-range: 207.34.xxx.xx/32
    spec:
      rules:
      - host: myapp.rabello.me
        http:
          paths:
          - path: "/"
            backend:
              serviceName: custom-http-backend
              servicePort: 80
    

    应用规范:k apply -f my-app-ingress.yaml

    使用命令检查入口:

    ➜  ~ k get ing
    NAME             HOSTS              ADDRESS          PORTS   AGE
    my-app-ingress   myapp.rabello.me   146.148.xx.xxx   80      36m
    

    就是这样!

    如果我在家里使用我的白名单 ip 进行测试,则会显示自定义页面,但如果我尝试在 4G 网络中使用手机访问,则会显示 nginx 默认页面。

    注意我在同一个命名空间中使用入口和服务,如果你需要使用不同的命名空间,你需要使用ExternalName

    希望对你有帮助!

    参考资料: kubernetes deployments

    kubernetes service

    nginx ingress

    nginx annotations

    【讨论】:

    【解决方案3】:

    您需要创建和部署自定义默认后端,这将返回自定义错误页面。按照doc 部署自定义默认后端并通过修改部署 yaml 来配置 nginx 入口控制器以使用此自定义默认后端。

    自定义默认后端的部署yaml为here,源代码为here

    【讨论】:

      猜你喜欢
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-12
      • 2023-04-03
      • 1970-01-01
      • 2012-06-29
      • 1970-01-01
      相关资源
      最近更新 更多