如何在Kubernetes中使用ConfigMap配置Helm NginX Ingress控制器

36

我找到了一份关于如何使用ConfigMap配置您的NginX Ingress控制器的文档:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/

不幸的是,我不知道如何从我的Ingress控制器中加载该ConfigMap,并且无法在任何地方找到相关信息。

我的Ingress控制器:

helm install --name ingress --namespace ingress-nginx --set rbac.create=true,controller.kind=DaemonSet,controller.service.type=ClusterIP,controller.hostNetwork=true stable/nginx-ingress

我的配置映射:

kind: ConfigMap
apiVersion: v1
metadata:
  name: ingress-configmap
data:
  proxy-read-timeout: "86400s"
  client-max-body-size: "2g"
  use-http2: "false"

我的入口:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  tls:
    - hosts:
        - my.endpoint.net
      secretName: ingress-tls
  rules:
    - host: my.endpoint.net
      http:
        paths:
          - path: /
            backend:
              serviceName: web
              servicePort: 443
          - path: /api
            backend:
              serviceName: api
              servicePort: 443

我该如何让Ingress从ConfigMap加载配置?

14个回答

27

我已经成功地使用--dry-run --debug选项在helm install命令的结尾显示了Helm执行的YAML内容。然后我注意到控制器是使用--configmap={namespace-where-the-nginx-ingress-is-deployed}/{name-of-the-helm-chart}-nginx-ingress-controller来执行的。 为了加载您自己的ConfigMap,您需要使用自己的ConfigMap覆盖它(请查看命名空间)。

kind: ConfigMap
apiVersion: v1
metadata:
  name: {name-of-the-helm-chart}-nginx-ingress-controller
  namespace: {namespace-where-the-nginx-ingress-is-deployed}
data:
  proxy-read-timeout: "86400"
  proxy-body-size: "2g"
  use-http2: "false"

配置属性列表可以在这里找到。


4
“--configmap” 不是helm的一个被识别的标志。虽然我能够轻松创建配置映射和nginx ingress,但我仍然不知道如何将它们联系在一起。Ingress没有从配置映射中获取属性。 - ScottSummers
1
不要使用“--configmap”选项,将您的configmap命名为Helm内部调用configmap的方式相同。如果您再次阅读我的答案,您将能够找到它。 - NeverEndingQueue
1
应用的配置映射名称为{helm图表名称}-ingress-nginx-ingress-controller,将从部署图表的命名空间中获取。在答案中添加注释以防止编辑被拒绝。非常感谢您的帮助@NeverEndingQueue!干杯!!! - ScottSummers
1
很高兴能够帮忙。感谢您的编辑,我稍微调整了一下。我认为它不是:{name-of-the-helm-chart}-ingress-nginx-ingress-controller,而是:{name-of-the-helm-chart}-nginx-ingress-controller。对吗? - NeverEndingQueue
1
当我试图在现有的入口上添加新的配置映射时,我注意到存在一个名为“nginx-ingress-ingress-nginx-controller”的现有配置映射,没有任何数据,因此必须添加一个具有不同名称的新配置映射,并编辑部署以包括这个配置映射? - rishi
显示剩余6条评论

18

也可以在安装时传递配置文件属性:

helm install stable/nginx-ingress --name nginx-ingress --set controller.config.use-forwarded-headers='"true"'

注意:对于非字符串值,必须在双引号内使用单引号才能使其正常工作。


谢谢您提供的有效答案。但我想知道如何将http-snippet作为参数传递给helm图表呢?例如:"http-snippet": "proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=mycache:32m use_temp_path=off max_size=4g inactive=1h;"。谢谢。 - rishi

5
如果您使用helm install安装了ingress-nginx,且没有传递显式值以指定nginx控制器应查看哪个configmap,则默认值似乎是{namespace}/{release-name}-nginx-ingress-controller。这是由https://github.com/helm/charts/blob/1e074fc79d0f2ee085ea75bf9bacca9115633fa9/stable/nginx-ingress/templates/controller-deployment.yaml#L67生成的。(如果链接失效,请查看类似的内容)。
要验证,请找到用于安装ingress-nginx chart的命令,并在命令后面添加--dry-run --debug。这将显示Tiller生成的yaml文件,以便应用于集群。行# Source: nginx-ingress/templates/controller-deployment.yaml开始控制器部署,其中有一个arg--configmap=。这个arg的值就是控制器需要感知和使用来更新自己的.conf文件的ConfigMap名称。它可以被显式地传递,但如果没有,则会有一个默认值。
如果创建了正确命名的ConfigMap,则控制器的日志将显示它捕获了配置更改并重新加载自身。可以使用kubectl logs <pod-name-of-controller> -n <namespace-arg-if-not-in-default-namespace>进行验证。我的日志消息包含文本Configuration changes detected, backend reload required.如果ConfigMap名称错误,则不会出现这些日志消息。
我认为官方文档在这方面的说明是不够充分的,但也许我是错的?我会尝试提交具有这些详细信息的PR。希望更了解此问题的人能帮助澄清这些细节,以便人们不必无谓地摸索。感谢您的文章。

4
在使用terraform安装图表时,可以按照以下方式设置配置值:
resource "helm_release" "ingress_nginx" {
  name       = "nginx"
  repository = "https://kubernetes.github.io/ingress-nginx/"
  chart      = "ingress-nginx"

  set {
    name  = "version"
    value = "v4.0.2"
  }
  set {
    name  = "controller.config.proxy-read-timeout"
    value = "86400s"
  }
  set {
    name  = "controller.config.client-max-body-size"
    value = "2g"
  }
  set {
    name  = "controller.config.use-http2"
    value = "false"
  }
}

4

如果您想在部署nginx-ingress-controller时使用自己的配置,您可以在原始nginx-ingress Helm图表上创建一个包装器Helm图表,并提供您自己的values.yaml,其中可以有自定义配置。

这里使用Helm 3。

创建一个图表:

$ helm create custom-nginx
$ tree custom-nginx

因此,我的图表结构如下:

custom-nginx/
├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

这里还有一些额外的内容。具体来说,我不需要完整的templates/目录及其所有内容,所以我会将它们删除:

$ rm custom-nginx/templates/*
$ rmdir custom-nginx/templates

现在,图表结构应如下所示:
custom-nginx/
├── Chart.yaml
├── charts
└── values.yaml

因为我们需要将原始的nginx-ingress图表作为依赖项包含在内,所以我的Chart.yaml看起来像这样:

 $ cat custom-nginx/Chart.yaml 
apiVersion: v2
name: custom-nginx
description: A Helm chart for Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 1.39.1

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
appVersion: 0.32.0

dependencies:
- name: nginx-ingress
  version: 1.39.1
  repository: https://kubernetes-charts.storage.googleapis.com/ 

这里,appVersionnginx-controller Docker 镜像的版本,而 version 与我使用的 nginx-ingress chart 版本相匹配。

最后一件事是提供自定义配置。这是我的自定义配置的简化版本:

$ cat custom-nginx/values.yaml 
# Default values for custom-nginx.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

nginx-ingress:
  controller:
    ingressClass: internal-nginx
    replicaCount: 1
    service:
      externalTrafficPolicy: Local
    publishService:
      enabled: true
    autoscaling:
      enabled: true
      minReplicas: 1
      maxReplicas: 3
      targetCPUUtilizationPercentage: "80"
      targetMemoryUtilizationPercentage: "80"
    resources:
      requests:
        cpu: 1
        memory: 2Gi
      limits:
        cpu: 1
        memory : 2Gi
    metrics:
      enabled: true
    config:
      compute-full-forwarded-for: "true"

我们可以在https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/上检查可用于配置(values.yaml中的config部分)的密钥。
其余的配置可以在此处找到:https://github.com/helm/charts/tree/master/stable/nginx-ingress#configuration 一旦设置好配置,只需下载您的图表依赖项。
$ helm dependency update <path/to/chart>

在部署图表之前,基本检查是一种良好的实践:

$ helm lint <path/to/chart>
$ helm install --debug --dry-run --namespace <namespace> <release-name> <path/to/chart>

部署您的图表(这将使用自定义配置部署您的nginx-ingress-controller)。

另外,由于现在有了一个图表,您可以升级和回滚您的图表。


没有必要提供一个包装图表来提供和配置入口nginx helm图表 - 这并不回答问题,而是“如何集中默认的nginx配置” - 对于问题。在部署图表时使用values.config而不是“非包装”即可回答问题(已经给出)。我理解你的方法也是人们可能寻找的,但它占据了你回答的95%,而这并不是被问到的。这使得它过于复杂 :) 在我看来 - Eugen Mayer

3
根据NeverEndingQueue的答案,我想为Kubernetes v1.23 / Helm 3提供更新。
这是我的安装命令和--dry-run --debug部分: helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx --namespace ingress-nginx --create-namespace --dry-run --debug 这是我们需要从上述命令生成的输出中获取的部分:
apiVersion: apps/v1
kind: DaemonSet
metadata:
  ...
spec:
  ...
  template:
    ...
    spec:
      dnsPolicy: ClusterFirst
      containers:
        - name: controller
          ...
          args:
            - /nginx-ingress-controller
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
            - --...
            - --configmap=${POD_NAMESPACE}/ingress-nginx-controller
            - --...
            ....

我们需要这部分:--configmap=${POD_NAMESPACE}/ingress-nginx-controller
正如您所看到的,ConfigMap 的名称必须是 ingress-nginx-controller,并且命名空间必须是您在安装图表时使用的命名空间(例如,在我的示例中,这是 --namespace ingress-nginx,其中 {POD_NAMESPACE} 是您使用的命名空间)。
# nginx-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
data:
  map-hash-bucket-size: "128"

然后运行kubectl apply -f nginx-config.yaml来应用ConfigMap,nginx的pod将自动重新加载更新的配置。


要检查nginx配置是否已更新,请找到nginx的pod名称(如果您有几个节点,则可以使用任何一个):kubectl get pods -n ingress-nginx(或kubectl get pods -A
然后检查配置:kubectl exec -it ingress-nginx-controller-{generatedByKubernetesId} -n ingress-nginx cat /etc/nginx/nginx.conf 更新: 正确的名称(即name: ingress-nginx-controller)显示在官方文档中。结论:不需要重新发明轮子。

2
我成功地通过configmap更新了nginx中的“large-client-header-buffers”。以下是我遵循的步骤。
  1. 在nginx ingress controller pod描述中找到configmap名称
kubectl -n utility describe pods/test-nginx-ingress-controller-584dd58494-d8fqr |grep configmap
      --configmap=test-namespace/test-nginx-ingress-controller

注意:在我的情况下,命名空间为“test-namespace”,配置映射名称为“test-nginx-ingress-controller”。
2. 创建一个 配置映射yaml
cat << EOF > test-nginx-ingress-controller-configmap.yaml 

kind: ConfigMap
apiVersion: v1
metadata:
  name: test-nginx-ingress-controller
  namespace: test-namespace
data:
  large-client-header-buffers: "4 16k"
EOF

注意:请根据第一步的查找结果替换命名空间配置映射名称

  1. 部署配置映射 yaml 文件
kubectl apply -f test-nginx-ingress-controller-configmap.yaml

然后您将看到更改在几分钟后更新到nginx控制器pod。
i.g.
kubectl -n test-namespace exec -it test-nginx-ingress-controller-584dd58494-d8fqr -- cat /etc/nginx/nginx.conf|grep large
    large_client_header_buffers     4 16k;


2

仅为确认@NeverEndingQueue的答案,配置映射的名称在nginx-controller pod规范中存在,因此如果您检查nginx-controller pod的yaml文件:kubectl get po release-name-nginx-ingress-controller-random-sequence -o yaml,在spec.containers下,您将找到类似以下内容:

  - args:
    - /nginx-ingress-controller
    - --default-backend-service=default/release-name-nginx-ingress-default-backend
    - --election-id=ingress-controller-leader
    - --ingress-class=nginx
    - --configmap=default/release-name-nginx-ingress-controller

例如,在命名空间default中需要创建一个名为release-name-nginx-ingress-controller的配置映射。
完成后,您可以通过检查日志来验证更改是否已生效。通常,您会看到类似以下内容的信息:
I1116 10:35:45.174127       6 event.go:278] Event(v1.ObjectReference{Kind:"ConfigMap", Namespace:"default", Name:"release-name-nginx-ingress-controller", UID:"76819abf-4df0-41e3-a3fe-25445e754f32", APIVersion:"v1", ResourceVersion:"62559702", FieldPath:""}): type: 'Normal' reason: 'CREATE' ConfigMap default/release-name-nginx-ingress-controller
I1116 10:35:45.184627       6 controller.go:141] Configuration changes detected, backend reload required.
I1116 10:35:45.396920       6 controller.go:157] Backend successfully reloaded.

1
当您使用具有必要键值数据的ConfigMap配置时,Ingress控制器会获取此信息并将其插入到嵌套的nginx-ingress-controller Pod的原始配置文件/etc/nginx/nginx.conf中,因此之后很容易通过检查相应Pod内的实际nginx.conf来验证是否成功反映了ConfigMap的值。 您还可以从相关的nginx-ingress-controller Pod中检查日志,以检查ConfigMap数据是否已重新加载到后端nginx.conf,或者如果未加载,则调查原因。

1
谢谢。是的,ConfigMap 的更改很好地影响了内部的 nginx.conf。 如果有人想要检查 NginX 配置是否在外部受到影响(而不必进入 pod),可以设置 server_tokens offserver_tokens on,并注意 NginX 是否在 HTTP 标头中宣传自己。 - NeverEndingQueue
如果检测到ConfigMap,控制器应该看到哪些日志?因为我似乎已经按照这里的所有步骤操作了,但我不确定我的.conf文件是否在更新。 - Yehuda Makarov
例如,执行以下编程命令:kubectl exec -ndefault nginx-ingress-controller-b545558d8-829dz -- cat /etc/nginx/nginx.conf | grep tokens - mpen

1

更简单的方法是通过修改helm部署的值来完成。需要更改以输入到ConfigMap中的值现在位于controller.config.entries中。使用以下命令显示最新值:helm show values nginx-stable/nginx-ingress,并查找您正在运行的版本的格式。

我遇到了很多问题,因为所有在线引用都说controller.config,直到我使用上面的命令进行了检查。

输入值后,请使用以下命令升级:

helm upgrade -f <PATH_TO_FILE>.yaml <NAME> nginx-stable/nginx-ingress

为了确保,在当前的helm chart版本中,controller.config是正确的,不需要嵌套在https://github.com/kubernetes/ingress-nginx/blob/main/charts/ingress-nginx/templates/controller-configmap.yaml#L26之后。源代码来自于https://github.com/kubernetes/ingress-nginx/blob/main/charts/ingress-nginx/templates/controller-configmap.yaml#L26 - 版本4.0.13。 - Eugen Mayer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接