k8s icon indicating copy to clipboard operation
k8s copied to clipboard

Deployment with Nginx Ingress failed

Open yurymkomarov opened this issue 3 years ago • 8 comments

Hello all, I'm trying to deploy portainer to my EKS using terraform.

Here is my code:

resource "helm_release" "portainer" {
  name             = "portainer"
  repository       = "https://portainer.github.io/k8s/"
  chart            = "portainer"
  namespace        = "portainer"
  lint             = false
  cleanup_on_fail  = true
  create_namespace = true

  values = [yamlencode({
    service = { type = "ClusterIP" }

    ingress = {
      enabled     = true
      annotations = { "kubernetes.io/ingress.class" = "nginx" }
      hosts       = [{ host = "portainer.${local.tfstate["route53"]["internal"]["name"]}" }]
    }

    persistence = { storageClass = "gp2" }
  })]
}

Here is my error output:

helm_release.portainer: Creating...

Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: ValidationError(Ingress.spec.rules[0].http): missing required field "paths" in io.k8s.api.networking.v1beta1.HTTPIngressRuleValue

I've said "okay" and added "paths":

    ingress = {
      enabled     = true
      annotations = { "kubernetes.io/ingress.class" = "nginx" }
      hosts = [{
        host  = "portainer.${local.tfstate["route53"]["internal"]["name"]}"
        paths = ["/"]
      }]
    }

And now I see this error:

helm_release.portainer: Creating...

Error: template: portainer/templates/ingress.yaml:35:21: executing "portainer/templates/ingress.yaml" at <.path>: can't evaluate field path in type interface {}

What I'm doing wrong? 😐

yurymkomarov avatar Apr 05 '21 07:04 yurymkomarov

@funkypenguin you are the project main maintainer as I understand. Do u have some ideas?

yurymkomarov avatar Apr 05 '21 08:04 yurymkomarov

Hey @yurymkomarov!

Looking at the template (below), both hosts and paths seem to be interpreted using range:

  {{- range .Values.ingress.hosts }}
    - host: {{ .host | quote }}
      http:
        paths:
        {{- range .paths }}
          - path: {{ .path | default "/" }}
            backend:

Therefore I'd suggest that you try something like this?

    ingress = {
      enabled     = true
      annotations = { "kubernetes.io/ingress.class" = "nginx" }
      hosts = [{
        host  = "portainer.${local.tfstate["route53"]["internal"]["name"]}"
        paths = [{
          path = "/"
        }]
      }]
    }

If this works, then we probably have to update the README and values.yaml to more clearly indicate how to pass these arguments to the chart!

Cheers! D

funkypenguin avatar Apr 05 '21 09:04 funkypenguin

Not sure is related to the same thing, but the result is the same. I am using the example from the Portainer website.

helm install --create-namespace -n portainer portainer portainer/portainer \ --set service.type=ClusterIP \ --set ingress.enabled=true \ --set ingress.annotations='kubernetes.io/ingress.class: nginx' \ --set ingress.hosts.host=portainer.example.io

and I receive an error

coalesce.go:196: warning: cannot overwrite table with non table for annotations (map[]) coalesce.go:199: warning: destination for hosts is a table. Ignoring non-table value [map[host: paths:[]]] Error: template: portainer/templates/ingress.yaml:31:15: executing "portainer/templates/ingress.yaml" at <.host>: can't evaluate field host in type interface {}

Can you please tell me what I am doing wrong.

Many thanks

MarkLFT avatar Apr 17 '21 13:04 MarkLFT

@funkypenguin do you mind having a look at @MarkLFT problem?

deviantony avatar Apr 18 '21 21:04 deviantony

Just to let you know I have got around this issue by using a value.yaml and put all the ingress values in there. So I think the issue here is just I cannot format the set values correctly.

MarkLFT avatar Apr 20 '21 07:04 MarkLFT

Hello @funkypenguin! I had the same problem today and I solved this way.

My first attempt was to create the required structure in values.yaml or in my custom values.yaml file and then execute helm template/install with flag -f <path_to_my_values.yaml>. I create the structure like this (my custom values.yaml)

ingress:
  enabled: true
  annotations: {}
  hosts:
    - host: 'portainer.minikube.local'
      paths:
      - path: '/'

And this is the structure of vaules.yaml (default)

ingress:
  enabled: false
  annotations: {}
  hosts:
    - host:
      paths: []

What can we see there? Right! There is no ingress.hosts[].paths[].path

My second attempt was to pass the right structure by --set flags. helm template portainer/portainer --set ingress.hosts[0].host="portainer.minikube.local" --set ingress.hosts[0].paths[0].path="/" After that templating was successfull

# Source: portainer/templates/ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: RELEASE-NAME-portainer
  namespace: portainer1
  labels:
    helm.sh/chart: portainer-1.0.14
    app.kubernetes.io/name: portainer
    app.kubernetes.io/instance: RELEASE-NAME
    app.kubernetes.io/version: "ce-latest-ee-2.4.0"
    app.kubernetes.io/managed-by: Helm
spec:
  rules:
    - host: "portainer.minikube.local"
      http:
        paths:
          - path: /
            backend:
              serviceName: RELEASE-NAME-portainer
              servicePort: 9000

So, the problem is that there is no mention in the documentation about passing custom variables by array and not by map.

0m1xa avatar May 03 '21 15:05 0m1xa

Dear @funkypenguin

This is caused because networking.k8s.io/v1beta1 is deprecated since 1.19.

Ingress

The extensions/v1beta1 and networking.k8s.io/v1beta1 API versions of Ingress is no longer served as of v1.22.

  • Migrate manifests and API clients to use the networking.k8s.io/v1 API version, available since v1.19.
  • All existing persisted objects are accessible via the new API
  • Notable changes:
    • spec.backend is renamed to spec.defaultBackend
    • The backend serviceName field is renamed to service.name
    • Numeric backend servicePort fields are renamed to service.port.number
    • String backend servicePort fields are renamed to service.port.name
    • pathType is now required for each specified path. Options are Prefix, Exact, and ImplementationSpecific. To match the undefined v1beta1 behavior, use ImplementationSpecific.

IngressClass

The networking.k8s.io/v1beta1 API version of IngressClass is no longer served as of v1.22.

  • Migrate manifests and API clients to use the networking.k8s.io/v1 API version, available since v1.19.
  • All existing persisted objects are accessible via the new API
  • No notable changes __Deprecated API Migration Guide

In file: ingress.yml

Thanks

khooz avatar Dec 21 '21 08:12 khooz

Any Updates for this topic? Because we currently cannot update Portainer because of this. There are pending Merge Requests, which will solve this topic: #91 or #89

swarnat avatar Jan 18 '22 10:01 swarnat