Patches

3 minute read

A patch can be used to apply parameter values to their necessary resources for each trial.

Patch Spec

The patch spec is a list of patches that can be applied. Each patch must contain a patch parameter. Optionally, a patch type, target reference, and readiness gate may be specified.

Additional details for the patch spec can be found in the patch reference.

Concepts

Patch Types

Patches can be one of three types: Strategic, Merge, or JSON.

Strategic Merge Patch

With a strategic merge patch, a list is either replaced or merged depending on its patch strategy. The patch strategy is specified by the value of the patchStrategy key in a field tag in the Kubernetes source code.

A strategic merge patch is the default patch type if type is not specified.

The following example uses a strategic merge patch to patch a pod with a container named container-name and set the cpu requests to the value of the cpu parameter for the current trial. Note the inclusion of the trailing m to specify millicore units.

spec:
  patches:
  - type: strategic
    patch: |
      spec:
        template:
          spec:
            containers:
            - name: container-name
              resources:
                requests:
                  cpu: "{{ .Values.cpu }}m"      

Merge Patch

With a merge patch, a resource is explicitly added, updated, or removed. A merge patch follows the syntax defined in rfc7386.

The following will update the number of replicas to the value of the replicas parameter for the current trial.

spec:
  patches:
  - type: merge
    patch: |
      spec:
        replicas: {{ .Values.replicas }}      

JSON Patch

With a JSON patch, a resource is modified through various operation directives. A JSON Patch follows the syntax defined in rfc6902.

The following example uses a JSON patch to patch the first container in a pod and set the cpu limits to the value of the cpu parameter for the current trial.

spec:
  patches:
  - type: json
    patch: |
      [
        { "op": "replace", "path": "/spec/template/spec/containers/0/resources/limits/cpu",  "value": "{{ .Values.cpu }}m" }
      ]      

Example

While any of the above patch types would work for this example, we’ll use a strategic merge patch to apply the suggested parameters to our resources. We’ll be targeting the frontend and product catalog deployments to specify the resource constraints.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
apiVersion: optimize.stormforge.io/v1beta2
kind: Experiment
metadata:
  name: shopping
  labels:
    stormforge.io/application: shopping
    stormforge.io/scenario: 20-user
spec:
  parameters:
  - name: frontendCpu
    min: 50
    max: 1000
    baseline: 100
  - name: frontendMemory
    min: 16
    max: 512
    baseline: 64
  - name: catalogCpu
    min: 50
    max: 1000
    baseline: 100
  - name: catalogMemory
    min: 16
    max: 512
    baseline: 64
  patches:
  - targetRef:
      kind: Deployment
      apiVersion: apps/v1
      name: frontend
    patch: |
      spec:
        template:
          spec:
            containers:
            - name: server
              resources:
                limits:
                  cpu: "{{ .Values.frontendCpu }}m"
                  memory: "{{ .Values.frontendMemory }}Mi"
                requests:
                  cpu: "{{ .Values.frontendCpu }}m"
                  memory: "{{ .Values.frontendMemory }}Mi"      
  - targetRef:
      kind: Deployment
      apiVersion: apps/v1
      name: productcatalogservice
    patch: |
      spec:
        template:
          spec:
            containers:
            - name: server
              resources:
                limits:
                  cpu: "{{ .Values.catalogCpu }}m"
                  memory: "{{ .Values.catalogMemory }}Mi"
                requests:
                  cpu: "{{ .Values.catalogCpu }}m"
                  memory: "{{ .Values.catalogMemory }}Mi"      

Now that we’ve got our patches added, we can add our metrics to measure the impact of our changes.

Last modified August 25, 2021