Search code examples
kubernetesopenshiftkubernetes-ingressargocdkustomize

Kustomize Patch Ingress Issue - Go construct


I am new to kustomize and trying to figure out how to patch my ingress that is running via OpenShift Container Platform.

The base config works fine and the overlay was working until I introduced my ingress overlay patch. For reference the patch-service overlay does work so I am pretty sure my structure and links are all good, however the error I get on my project when syncronising to OpenShift (via ArgoCD) is:

one or more objects failed to apply, reason: Ingress in version "v1" cannot be handled as a Ingress: json: cannot unmarshal number into Go struct field IngressServiceBackend.spec.defaultBackend.service.port of type v1.ServiceBackendPort (retried 5 times).

Application Repo Structure

|mssql-example
├── base
│   ├── deployment.yaml
│   ├── ingress.yaml
│   ├── kustomization.yaml
│   ├── storage.yaml
│   └── service.yaml
└── overlays
    ├── nprd-dev
    │   ├── **patch-ingress.yaml**
    │   ├── patch-service.yaml
    │   └── kustomization.yaml
    ├── nprd-sit
    │   ├── patch-ingress.yaml
    │   ├── patch-service.yaml
    │   └── kustomization.yaml
    └── nprd-uat
    │   ├── patch-ingress.yaml
    │   ├── patch-service.yaml
    │   └── kustomization.yaml

mssql-example\base\ingress.yaml

---
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
  name: mssql-example-adc
  annotations:
    ingress.citrix.com/frontend-ip: 192.168.1.10
    ingress.citrix.com/insecure-port: '1433'
    ingress.citrix.com/insecure-service-type: tcp
    kubernetes.io/ingress.class: citrix-vpx
spec:
  defaultBackend:
    service:
      name: mssql-service
      port:
        number: 31433

mssql-example\overlays\nprd-dev\kustomization.yaml

---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: ops-example-dev
resources:
  - ../../base
patches:
  - path: patch-ingress.yaml
    target:
      kind: Ingress
      version: v1
      name: mssql-example-adc
  - path: patch-service.yaml
    target:
      kind: Service
      version: v1
      name: mssql-example-tcp

mssql-example\overlays\nprd-dev\patch-ingress.yaml

---
- op: replace
  path: /metadata/name
  value: mssql-example-ingress-dev
- op: replace
  path: /spec/defaultBackend/service/port
  value: 31434

I think my path may be wrong, but I can't seem to work out how to correctly identify the replacement path for the spec when it is defaultBackend. I tried the path as /spec/defaultBackend/0/service/port and /spec/0/defaultBackend/service/port incase it was an array.


Solution

  • The error is telling you everything you need to know:

    cannot unmarshal number into Go struct field
    

    First, look at the format of your initial Ingress manifest:

    kind: Ingress
    apiVersion: networking.k8s.io/v1
    metadata:
      name: mssql-example-adc
      annotations:
        ingress.citrix.com/frontend-ip: 192.168.1.10
        ingress.citrix.com/insecure-port: '1433'
        ingress.citrix.com/insecure-service-type: tcp
        kubernetes.io/ingress.class: citrix-vpx
    spec:
      defaultBackend:
        service:
          name: mssql-service
          port:
            number: 31433
    

    Pay particular attention to the structure of spec.defaultBackend.service.port.

    Now, look at the output generated by your patch:

    $ kustomize build
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        ingress.citrix.com/frontend-ip: 192.168.1.10
        ingress.citrix.com/insecure-port: "1433"
        ingress.citrix.com/insecure-service-type: tcp
        kubernetes.io/ingress.class: citrix-vpx
      name: mssql-example-ingress-dev
    spec:
      defaultBackend:
        service:
          name: mssql-service
          port: 31434
    

    Do you see the difference? You've replaced a structured value:

    port:
      number: 31433
    

    With an integer:

    port: 31434
    

    Just update your patch to target ...service/port/number instead:

    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    resources:
    - ingress.yaml
    
    patches:
      - target:
          name: mssql-example-adc
        patch: |
          - op: replace
            path: /metadata/name
            value: mssql-example-ingress-dev
          - op: replace
            path: /spec/defaultBackend/service/port/number
            value: 31434
    

    Which results in:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        ingress.citrix.com/frontend-ip: 192.168.1.10
        ingress.citrix.com/insecure-port: "1433"
        ingress.citrix.com/insecure-service-type: tcp
        kubernetes.io/ingress.class: citrix-vpx
      name: mssql-example-ingress-dev
    spec:
      defaultBackend:
        service:
          name: mssql-service
          port:
            number: 31434