Use Case:
A User wants to gather information from a Kubernetes deployment and leverage it as a variable later on. These values can be leveraged in other Workflows or in a Pipeline! In order to retrieve these specific values, we leverage something called the JSONPATH=`` in the Kubectl tool. This lets the user navigate through a Kubernetes object and specify a specific field they want to view.
Below is what a deployment.json looks like
Run this command to describe the deployment
kubectl describe deployment frontend -o=json
This is the result
{
"apiVersion": "extensions/v1beta1",
"kind": "Deployment",
"metadata": {
"annotations": {
"deployment.kubernetes.io/revision": "1",
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"annotations\":{\"kubernetes.io/change-cause\":\"kubectl apply --kubeconfig=config --filename=manifests.yaml --record=true\"},\"finalizers\":[],\"labels\":{\"app\":\"guestbook-test\"},\"name\":\"frontend\",\"namespace\":\"dev\",\"ownerReferences\":[]},\"spec\":{\"replicas\":3,\"selector\":{\"matchExpressions\":[],\"matchLabels\":{\"app\":\"guestbook\",\"harness.io/track\":\"stable\",\"tier\":\"frontend\"}},\"template\":{\"metadata\":{\"annotations\":{},\"finalizers\":[],\"labels\":{\"app\":\"guestbook\",\"harness.io/release-name\":\"release-cbb5dd9c-4c21-3704-8a90-1cf22d9b4300\",\"harness.io/track\":\"stable\",\"tier\":\"frontend\"},\"ownerReferences\":[]},\"spec\":{\"containers\":[{\"args\":[],\"command\":[],\"env\":[{\"name\":\"GET_HOSTS_FROM\",\"value\":\"dns\"}],\"envFrom\":[],\"image\":\"gcr.io/google-samples/gb-frontend:v4\",\"name\":\"php-redis\",\"ports\":[{\"containerPort\":80}],\"resources\":{\"limits\":{},\"requests\":{\"cpu\":\"100m\",\"memory\":\"100Mi\"}},\"volumeMounts\":[]}],\"hostAliases\":[],\"imagePullSecrets\":[],\"initContainers\":[],\"nodeSelector\":{},\"tolerations\":[],\"volumes\":[]}}}}\n",
"kubernetes.io/change-cause": "kubectl apply --kubeconfig=config --filename=manifests.yaml --record=true"
},
"creationTimestamp": "2019-12-14T01:02:51Z",
"generation": 1,
"labels": {
"app": "guestbook-test"
},
"name": "frontend",
"namespace": "dev",
"resourceVersion": "1105661",
"selfLink": "/apis/extensions/v1beta1/namespaces/dev/deployments/frontend",
"uid": "73a8d311-1e0d-11ea-9b03-42010a8a0105"
},
"spec": {
"progressDeadlineSeconds": 600,
"replicas": 3,
"revisionHistoryLimit": 10,
"selector": {
"matchLabels": {
"app": "guestbook",
"harness.io/track": "stable",
"tier": "frontend"
}
},
"strategy": {
"rollingUpdate": {
"maxSurge": "25%",
"maxUnavailable": "25%"
},
"type": "RollingUpdate"
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"app": "guestbook",
"harness.io/release-name": "release-cbb5dd9c-4c21-3704-8a90-1cf22d9b4300",
"harness.io/track": "stable",
"tier": "frontend"
}
},
"spec": {
"containers": [
{
"env": [
{
"name": "GET_HOSTS_FROM",
"value": "dns"
}
],
"image": "gcr.io/google-samples/gb-frontend:v4",
"imagePullPolicy": "IfNotPresent",
"name": "php-redis",
"ports": [
{
"containerPort": 80,
"protocol": "TCP"
}
],
"resources": {
"requests": {
"cpu": "100m",
"memory": "100Mi"
}
},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File"
}
],
"dnsPolicy": "ClusterFirst",
"restartPolicy": "Always",
"schedulerName": "default-scheduler",
"securityContext": {},
"terminationGracePeriodSeconds": 30
}
}
},
"status": {
"availableReplicas": 3,
"conditions": [
{
"lastTransitionTime": "2019-12-14T01:02:51Z",
"lastUpdateTime": "2019-12-14T01:03:13Z",
"message": "ReplicaSet \"frontend-d6b644566\" has successfully progressed.",
"reason": "NewReplicaSetAvailable",
"status": "True",
"type": "Progressing"
},
{
"lastTransitionTime": "2019-12-16T20:23:00Z",
"lastUpdateTime": "2019-12-16T20:23:00Z",
"message": "Deployment has minimum availability.",
"reason": "MinimumReplicasAvailable",
"status": "True",
"type": "Available"
}
],
"observedGeneration": 1,
"readyReplicas": 3,
"replicas": 3,
"updatedReplicas": 3
}
}
Key Questions:
How does a developer navigate through this?
What pieces of information can we leverage from this?
Online Resources:
To better understand how to traverse the Kubernetes Object YAML and manipulate certain fields please review this doc from Kubernetes: kubectl Cheat Sheet | Kubernetes
Sample Commands
Example 1
This Command gets a deployment called frontend in the namespace dev, we output the object “-o” and specify the JSONPATH of the image. We dump it out to JSON file and run the cut command to get the specific version tag of the image.
kubectl get deployment frontend -n dev -o jsonpath='{.spec.template.spec.containers[].image}' >> deployment.json | cut -d':' -f 2
The Result of the above command
Output: v4
Example 2
If you want to get information about the containers in the deployment, run the command
kubectl get deployment frontend -n dev -o jsonpath='{.spec.template.spec.containers}'
The result is a map with values from the Deployment YAML
[map[env:[map[name:GET_HOSTS_FROM value:dns]] image:gcr.io/google-samples/gb-frontend:v4 imagePullPolicy:IfNotPresent name:php-redis ports:[map[containerPort:80 protocol:TCP]] resources:map[requests:map[cpu:100m memory:100Mi]] terminationMessagePath:/dev/termination-log terminationMessagePolicy:File]]
Example 3
If you want to run a command that gets information about the template spec, run this command
kubectl get deployment frontend -n dev -o jsonpath='{.spec.template.spec}'
The result is a map with all the information about the Spec
map[containers:[map[env:[map[name:GET_HOSTS_FROM value:dns]] image:gcr.io/google-samples/gb-frontend:v4 imagePullPolicy:IfNotPresent name:php-redis ports:[map[containerPort:80 protocol:TCP]] resources:map[requests:map[cpu:100m memory:100Mi]] terminationMessagePath:/dev/termination-log terminationMessagePolicy:File]] dnsPolicy:ClusterFirst restartPolicy:Always schedulerName:default-scheduler securityContext:map terminationGracePeriodSeconds:30]
Example 4
If you want to get information about the deployment template metadata, you would run a command like this:
kubectl get deployment frontend -n dev -o jsonpath='{.spec.template.metadata}'
The result of this command is
map[creationTimestamp: labels:map[app:guestbook harness.io/release-name:release-cbb5dd9c-4c21-3704-8a90-1cf22d9b4300 harness.io/track:stable tier:frontend]]
Example 5
If you just want to target the replicas of deployment leverage this command.
kubectl get deployment frontend -n dev -o jsonpath='{.spec.replicas}'
The result of this command is 3
How might someone leverage this in Harness?
Conclusion
Using the samples commands, users can gather data from their deployments and output them in the context to be leveraged in future shell scripts within a worklow or pipeline. It can be also used as a Summary JIRA of the deployment. Hope this spurs some creativity within our canary community!