0

Here my PatchStrategicMergeTransformer:

apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
  name: not-important-to-example
paths:
- patches/add-resources-patch.yaml

My patches/add-resources-patch.yaml:

apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
  name: portal
spec:
  template:
    spec:
      containers:
      - name: portal
        resources:
          limits:
            cpu: "1"
            memory: 512Mi
          requests:
            cpu: "0.5"
            memory: 256Mi

My base/deploymentconfig.yaml:

apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
  name: portal
spec:
  replicas: 1
  strategy:
    type: Rolling
    rollingParams:
      intervalSeconds: 1
      maxSurge: 1
      maxUnavailable: 0
      timeoutSeconds: 180
  template:
    spec:
      volumes:
      - name: environments
        configMap:
          name: portal
      containers:
        - name: portal
          image: portal
          ports:
            - containerPort: 8080
          volumeMounts:
          - name: environments
            mountPath: /var/www/html/environments-ui
          readinessProbe:
            failureThreshold: 3
            tcpSocket:
              port: 8080
            timeoutSeconds: 5
            periodSeconds: 60
            initialDelaySeconds: 5
          livenessProbe:
            failureThreshold: 3
            tcpSocket:
              port: 8080
            timeoutSeconds: 1
            periodSeconds: 10
            initialDelaySeconds: 5
          startupProbe:
            failureThreshold: 30
            tcpSocket:
              port: 8080
            timeoutSeconds: 2
            periodSeconds: 10
            initialDelaySeconds: 5

My patch is trying to add resources to container portal. Resources are added, but base container definition is removed instead of keep them:

apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
  labels:
    CodiAplicacio: "2986"
    CodiEntitat: CTT
    CodiInap: GAA
    CodiServei: "7_881"
    app.kubernetes.io/component: portal
    app.kubernetes.io/managed-by: kustomize
    app.kubernetes.io/name: portal
    app.kubernetes.io/part-of: espaidoc
    app.kubernetes.io/version: 1.0.0
    stage: pre
  name: portal
spec:
  replicas: 1
  strategy:
    rollingParams:
      intervalSeconds: 1
      maxSurge: 1
      maxUnavailable: 0
      timeoutSeconds: 180
    type: Rolling
  template:
    metadata:
      labels:
        CodiAplicacio: "2986"
        CodiEntitat: CTT
        CodiInap: GAA
        CodiServei: "7_881"
        app.kubernetes.io/component: portal
        app.kubernetes.io/managed-by: kustomize
        app.kubernetes.io/name: portal
        app.kubernetes.io/part-of: espaidoc
        app.kubernetes.io/version: 1.0.0
        stage: pre
    spec:
      containers:
      - name: portal
        resources:
          limits:
            cpu: "1"
            memory: 512Mi
          requests:
            cpu: "0.5"
            memory: 256Mi
      volumes:
      - configMap:
          name: portal
        name: environments

Any ideas?

Jordi
  • 20,868
  • 39
  • 149
  • 333

1 Answers1

2

Your problem is that you are patching a DeploymentConfig resource. Kustomize uses information from the schema for a given resource to determine how to handle merging lists. For native Kubernetes resources like Deployments (and Pods and ConfigMaps and Secrets, etc), Kustomize already knows how to the right thing.

A DeploymentConfig is not a native Kubernetes resource, so Kustomize falls back on default behavior which doesn't yield the results you want.

The simplest solution is to stop using DeploymentConfig resources and just use regular Deployment resources. This is in fact what the OpenShift documentation suggests:

Both Kubernetes Deployment objects and OpenShift Container Platform-provided DeploymentConfig objects are supported in OpenShift Container Platform; however, it is recommended to use Deployment objects unless you need a specific feature or behavior provided by DeploymentConfig objects.


If you can't make that change, then you will need to (a) extract the OpenAPI schema for DeploymentConfig resources from OpenShift and then (b) make this information available to Kustomize.

You can get openapi schemas from the /openapi/v2 endpoint on your OpenShift server. To place the schemas in a file named openapi.json, run something like this:

curl -o openapi.json -H "Authorization: Bearer $(oc whoami -t)" https://my.server.address:6443/openapi/v2

(You don't actually need the entire 500,000 line file, but I don't have time to strip it down right now -- I will try to update this answer later today.)

And then update your kustomization.yaml to include:

openapi:
  path: openapi.json

Now, running kustomize build with the examples from your question produces:

apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
  name: portal
spec:
  replicas: 1
  strategy:
    rollingParams:
      intervalSeconds: 1
      maxSurge: 1
      maxUnavailable: 0
      timeoutSeconds: 180
    type: Rolling
  template:
    spec:
      containers:
      - image: portal
        livenessProbe:
          failureThreshold: 3
          initialDelaySeconds: 5
          periodSeconds: 10
          tcpSocket:
            port: 8080
          timeoutSeconds: 1
        name: portal
        ports:
        - containerPort: 8080
        readinessProbe:
          failureThreshold: 3
          initialDelaySeconds: 5
          periodSeconds: 60
          tcpSocket:
            port: 8080
          timeoutSeconds: 5
        resources:
          limits:
            cpu: "1"
            memory: 512Mi
          requests:
            cpu: "0.5"
            memory: 256Mi
        startupProbe:
          failureThreshold: 30
          initialDelaySeconds: 5
          periodSeconds: 10
          tcpSocket:
            port: 8080
          timeoutSeconds: 2
        volumeMounts:
        - mountPath: /var/www/html/environments-ui
          name: environments
      volumes:
      - configMap:
          name: portal
        name: environments

Update 1

You can minimize the openapi definitions with this script (assuming you dump the output from curl into all.json):

jq '
    fromstream(
        {
            "swagger": .swagger,
            "info": .info,
            "definitions": [
            .definitions|to_entries[]|select(
                (.key|startswith("com.github.openshift.api.apps.v1.Deployment")) or
                (.key|startswith("io.k8s.apimachinery")) or
                (.key|startswith("io.k8s.api.core"))
            )]|from_entries
        }|tostream|del(select(.[0][-1]=="description"))|select(. != null)
    )
' < all.json > openapi.json

The resulting file is only 180K instead of 25MB (but the simpler option is still moving to Deployments instead of DeploymentConfigs).


You can find the files referenced in this answer here.

larsks
  • 277,717
  • 41
  • 399
  • 399