如何通过 Helm NginX Ingress 控制器使用 ConfigMap 配置 - Kubernetes

How to use ConfigMap configuration with Helm NginX Ingress controller - Kubernetes

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

不幸的是,我不知道也无法在任何地方找到如何从我的 Ingress 控制器加载该 ConfigMap。

我的入口控制器:

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 加载配置?

您应该在入口控制器部署清单中使用它

您拥有的是入口 yaml 而不是入口控制器部署 yaml,入口控制器是实际执行工作的 Pod,通常是 nginx 容器本身。在您共享的文档中可以找到此类配置的示例 here

更新

使用提供的示例,您还可以使用以下方式使用配置映射将配置加载到 nginx

     volumeMounts:
      - name: nginx-config
        mountPath: /etc/nginx/nginx.conf
       subPath: nginx.conf
    volumes:
     - name: nginx-config
       configMap:
       name: nginx-config 

nginx-config 包含您的 nginx 配置作为配置映射的一部分

我已经使用 helm install 命令末尾的 --dry-run --debug 选项成功地显示了 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"

可以找到配置属性列表 here

当你应用 ConfigMap 配置需要的键值数据时,Ingress 控制器获取此信息并将其插入到嵌套的 nginx-ingress-controller Pod 的原始配置文件 /etc/nginx/nginx.conf,因此它是之后很容易验证 ConfigMap 的值是否已成功反映,通过检查相应 Pod 中的实际 nginx.conf

您还可以查看相关nginx-ingress-controller Pod的日志,以检查ConfigMap数据是否已经重新加载到后端nginx.conf,如果没有则调查原因。

如果您使用 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 生成的。 (如果它是死的,请参见类似的 link)。

要自己验证,请尝试找到安装 ingress-nginx 图表时使用的命令,然后将 --dry-run --debug 添加到命令中。这将向您显示 Tiller 生成的要应用于集群的 yaml 文件。 # Source: nginx-ingress/templates/controller-deployment.yaml 行开始控制器部署,其 arg--configmap=。这个 arg 的值是需要控制器感知的 ConfigMap 的名称,并用于更新它自己的 .conf 文件。这可以显式传递,但如果不是,它将有一个默认值。

如果使用正确的名称创建 ConfigMap,控制器的日志将显示它选择了配置更改并自行重新加载。

这可以用 kubectl logs <pod-name-of-controller> -n <namespace-arg-if-not-in-default-namespace> 来验证。我的日志消息包含文本 Configuration changes detected, backend reload required. 如果 ConfigMap 名称错误,这些日志消息将不会出现。

我认为这方面的官方文档不必要地缺乏,但也许我不正确?我将尝试提交包含这些详细信息的 PR。知道更多的人应该帮助充实它们,这样人们就不需要无谓地偶然发现这个。

干杯,谢谢你的post。

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

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

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

我阅读了以上答案,但无法正常工作。

对我有用的是:

release_name=tcp-udp-ic

# add the helm repo from NginX and update the chart
helm repo add nginx-stable https://helm.nginx.com/stable
helm repo update

echo "- Installing -${release_name}- into cluster ..."

#delete the config map if already exists
kubectl delete cm tcp-udp-ic-cm

helm del --purge ${release_name}
helm upgrade --install ${release_name} \
--set controller.image.tag=1.6.0 \
--set controller.config.name=tcp-udp-ic-cm \
nginx-stable/nginx-ingress --version 0.4.0 #--dry-run --debug

# update the /etc/nginx/nginx.conf file with my attributes, via the config map
kubectl apply -f tcp-udp-ic-cm.yaml

tcp-udp-ic-cm.yaml 是:

kind: ConfigMap
apiVersion: v1
metadata:
  name: tcp-udp-ic-cm
  namespace: default
data:
  worker-connections : "10000"

基本上我需要用 helm 部署发布并设置将要使用的配置映射的名称。 Helm 创建配置映射但为空。然后我应用 config-map 文件以使用我的值更新 config-map 资源。这个序列是我唯一能做的。

如果你想在部署时提供自己的配置 nginx-ingress-controller,你可以在原始 nginx-ingress Helm chart 上有一个包装 Helm chart,并提供你自己的 values.yaml 它可以有自定义配置。

Using Helm 3 here.

创建图表:

$ 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-controllerdocker图像版本,version与我使用的nginx-ingress图表版本匹配。

唯一剩下的就是提供您的自定义配置。这是我的自定义配置的精简版:

$ 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)。

此外,由于您现在已经有了图表,因此可以升级和回滚图表。

一种更简单的方法是修改通过 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

只是为了确认上面@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.

使用 enable-underscores-in-headers=true 对我不起作用 enable-underscores-in-headers='"true"'

helm 安装nginx-ingressingress-nginx/ingress-nginx
--命名空间ingress-basic
--set controller.config.enable-underscores-in-headers=true

我设法通过 configmap 更新了 nginx 中的“large-client-header-buffers”。这是我遵循的步骤..

  1. 在 nginx 入口控制器 pod 描述中找到 configmap 名称
kubectl -n utility describe pods/test-nginx-ingress-controller-584dd58494-d8fqr |grep configmap
      --configmap=test-namespace/test-nginx-ingress-controller

注意:在我的例子中,命名空间是“test-namespace”,configmap 名称是“test-nginx-ingress-controller”

  1. 创建一个configmap 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

  1. 部署 configmap yaml
kubectl apply -f test-nginx-ingress-controller-configmap.yaml

然后你会看到更改在 mins 后更新到 nginx controller 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;

通过terraform安装chart时,配置值可以设置如下:

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"
  }
}

基于 我想提供 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,命名空间必须是您在图表安装期间使用的名称(即 {POD_NAMESPACE},在我的示例中是 --namespace ingress-nginx ).

# 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(s) 将 auto-reloaded 更新配置。


要检查 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

更新:

official docs 中显示了正确的名称(即 name: ingress-nginx-controller)。结论:无需重新发明轮子