...
This page will cover a few examples for patches that can be applied by users to their EC Deployment.
Changing Rollout Strategy
By default, the EC Deployment rollout strategy is set to RollingUpdate type. If for some reason you would like to change the rollout strategy for an EC Deployment, you can use EC Deployment's patch to change the rollout strategy. So the example will have us changing from the RollingUpdate to the Recreate type.
...
ECD Patch is meant to provide a flexible option for users to define and provision Kubernetes objects that suits their system architecture or to tailor the ECD to their preferred flavour.
Note |
---|
Patch is NOT the same as |
How it Works?
An ECD patch is the YAML that defined by the user which will be part of the payload sent by MZ Online to K8S API Server. The patch and patchType are part of the ECD CRD structure and they are on child object of ECD as well. While the use case is to have the ECD (and patch) to be created by MZ Online, technically an ECD can be created through K8S CLI. Since Operator is reconciling and monitoring the cluster through K8S API Server, there is no dependency on who or what is creating the ECD. After ECD is created in the cluster, Operator will be able to detect the change in desired state and act accordingly to match the actual state - the reconciliation process.
Based on current design, Operator is expecting the ECD patch to be in YAML format with respective parameters according to the patching strategy. Operator will attempt to patch the user defined YAML with the original YAML, resulting as 1 YAML before applying it to the K8S cluster.
Note |
---|
Great power comes with great complexity. With ECD patch such great flexibility, users are expected to have decent knowledge and understanding on Kubernetes and ECD CRD structure. Users are also expected to know and have a very good idea on what he / she attempts to patch. |
Patch Format
Patch comprises of 2 fields - Patch and Patch Type, embedded under different K8S object. Patch is the payload itself, which will be used to patch into the ECD K8S objects. Patch Type is the field where users can define the patching strategies used to patch the payload.
Current objects that can be patched through ECD are:
ECD (Deployments and Pods)
Services
HPA
Ingress
Below is the structure example under ECD (spec.patch and spec.patchType) :
Code Block |
---|
apiVersion: mz.digitalroute.com/v1alpha1
kind: ECDeployment
metadata:
name: anyECDeployment
namespace: anyNamespace
spec:
...
...
patchType: "application/merge-patch+json"
patch: |
...
... |
Below is the structure example under HPA (spec.autoscale.patch and spec.autoscale.patchType):
Code Block |
---|
apiVersion: mz.digitalroute.com/v1alpha1
kind: ECDeployment
metadata:
...
spec:
autoscale:
...
...
patchType: "application/merge-patch+json"
patch: |
spec:
... |
Info |
---|
There is a pipe “|” right after Patch, to indicate that below lines are multi lines YAML |
...
Patching Strategies
There are 3 types of strategies supported by MZ Operator Patch feature:
JSON Patch (RFC6902)
Merge Patch (RFC7386)
Strategic Merge Patch (K8S custom implementation of Merge Patch)
JSON Patch
As defined in RFC6902, a JSON Patch is a sequence of operations that are executed on the resource, e.g. {"op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ]}
. For more details on how to use JSON Patch, see the RFC.
Example below shows how to annotate an Ingress resource, so that it could be managed by Istio:
Code Block |
---|
apiVersion: mz.digitalroute.com/v1alpha1
kind: ECDeployment
metadata:
...
spec:
...
ingress:
patchType: "application/json-patch+json"
patch: |
- op: replace
path: /metadata/annotations/kubernetes.io~1ingress.class
value: istio |
Merge Patch
As defined in RFC7386, a Merge Patch is essentially a partial representation of the resource. The submitted JSON is "merged" with the current resource to create a new one, then the new one is saved. For more details on how to use Merge Patch, see the RFC.
Example below shows how to add a node selector to restrict this deployment (pod) to only run on nodes with label where disk type is SSD:
Code Block |
---|
apiVersion: mz.digitalroute.com/v1alpha1
kind: ECDeployment
metadata:
...
spec:
...
...
patchType: "application/merge-patch+json"
patch: |
spec:
template:
spec:
nodeSelector:
disktype: ssd |
Strategic Merge Patch
Strategic Merge Patch is a custom implementation of Merge Patch. For a detailed explanation of how it works and why it needed to be introduced, see API Conventions on Patch - Strategic Merge. In general, Strategic Merge Patch works better when it comes to merging K8S objects in a list. However, not all list can be merged, in detailed, please refer to object that comes with “Patch Strategy: Merge” in https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18
Example below shows how to add a host alias to the deployment (pod), which will basically add an entry into /etc/hosts
Code Block |
---|
apiVersion: mz.digitalroute.com/v1alpha1
kind: ECDeployment
metadata:
...
spec:
...
...
patchType: "application/strategic-merge-patch+json"
patch: |
spec:
template:
spec:
hostAliases:
- ip: "127.0.0.1"
hostnames:
- "dummy" |
Example below is taken from DRX repo - config/samples/patch/service.yaml. In ECD Services, a port 9092 is already defined. Using Strategic Merge Patch, we can add two more ports 9093 and 9094. On a side note, if we were to change the type from Strategic Merge Patch to Merge Patch, the port 9092 would have been removed after patch.
Code Block |
---|
services:
- spec:
type: ClusterIP
ports:
- port: 9092
protocol: TCP
targetPort: 9092
...
...
patchType: "application/strategic-merge-patch+json"
patch: |
spec:
ports:
- name: "port-1"
port: 9093
protocol: TCP
targetPort: 9093
- name: "port-2"
port: 9094
protocol: UDP
targetPort: 9094
... |
...
Samples
To help users to understand better, below are some samples that can get users started using ECD patch. Do note that “Before” is based on the ECD - which is the definition file for the desired state. while “After” is based on the conversion and logic processing done by Operator - which is the actual objects provisioning yaml to be applied to the cluster. As you might notice, there are a lot more objects that will be provisioned and handled by Operator itself.
Changing Rollout Strategy
Basically, an ECD will resulting in creating different K8S objects, 1 of them is Deployment object. The rollout strategy is default to RollingUpdate, through ECD patch we can change it to other strategy such as Recreate. The change can be seen on the spec.strategy.type (deployment) on After ECD Patch.
Before ECD Patch | After ECD Patch | ||||
---|---|---|---|---|---|
|
|
Setting Toleration
In example below, assuming a 3 nodes implementation K8S cluster, 2 nodes are tainted color=blue and 1 node is tainted color=red, the test is to add toleration to ECD so that it will get deployed into node tainted with color=red.
Code Block |
---|
$ k taint nodes kl-kube-node01.digitalroute.com kl-kube-node02.digitalroute.com color=blue:NoSchedule
node/kl-kube-node01.digitalroute.com tainted
node/kl-kube-node02.digitalroute.com tainted
$ k taint nodes kl-kube-node03.digitalroute.com color=red:NoSchedule
node/kl-kube-node03.digitalroute.com tainted |
Observe how toleration is being added and it get scheduled to the node tainted with color=red.
Before ECD Patch | After ECD Patch | ||||||
---|---|---|---|---|---|---|---|
|
|
Setting Environment Variable
There might be a case where you would like to add in an environment variable. In the example below, we will add one calls ENV where the value will be “dev”.
Before ECD Patch | After ECD Patch | ||||||
---|---|---|---|---|---|---|---|
|
|
Mounting a storage
In this scenario, we might want to attach a storage (be it temporary or permanent) in the ECD Pods, perhaps for Batch workflow processing files. In below example, we are attaching a temporary storage (live as long as Pod’s lifespan) and mounting it to the pod.
Before ECD Patch | After ECD Patch | ||||
---|---|---|---|---|---|
|
|
Removing an Object
We may also use ECD Patch to remove a provisioned K8S object. From mounting a storage example, now we can use the directive marker ( $patch: delete ) to remove the volume and volumeMount.
Before ECD Patch | After ECD Patch |
---|
Before ECD Patch | After ECD Patch | |
---|---|---|
|
...
|
|
...
|