From bcd50a5e2eea935b632e1e9ece51d8abc18c55d2 Mon Sep 17 00:00:00 2001 From: vinamra28 Date: Tue, 16 Jun 2020 21:50:12 +0530 Subject: [PATCH] Add kubernetes actions task in `kubectl` The task `kubectl-actions` is a generic task which can be used to perform k8s-actions. We take the whole script as a `params` whereas the existing task `kubectl-deploy` only works for deploying the pod and fulfills the specific criteria. Signed-off-by: vinamra28 --- kubectl/README.md | 201 ++++++++++++++----- kubectl/examples/kubectl-actions-run.yaml | 18 ++ kubectl/{ => examples}/taskrun-delete.yaml | 0 kubectl/{ => examples}/taskrun.yaml | 0 kubectl/kubectl-actions.yaml | 36 ++++ kubectl/kubectl-update-deployment-image.yaml | 26 +++ kubectl/{ => rbac}/clusterrole.yaml | 0 kubectl/{ => rbac}/clusterrolebinding.yaml | 0 8 files changed, 232 insertions(+), 49 deletions(-) create mode 100644 kubectl/examples/kubectl-actions-run.yaml rename kubectl/{ => examples}/taskrun-delete.yaml (100%) rename kubectl/{ => examples}/taskrun.yaml (100%) create mode 100644 kubectl/kubectl-actions.yaml create mode 100644 kubectl/kubectl-update-deployment-image.yaml rename kubectl/{ => rbac}/clusterrole.yaml (100%) rename kubectl/{ => rbac}/clusterrolebinding.yaml (100%) diff --git a/kubectl/README.md b/kubectl/README.md index 9442ac30b7..00c4f662d8 100644 --- a/kubectl/README.md +++ b/kubectl/README.md @@ -1,53 +1,58 @@ # Kubectl +# `kubectl-deploy` + This Task deploys (or delete) a Kubernates resource (pod). It uses [`kubectl`](https://kubernetes.io/zh/docs/reference/kubectl/kubectl/) for that. -## Install the Task +## Install ClusterRole + +**CAUTION:** The `clusterrole.yaml` is just a sample, should be modified based on real requirements to avoid potential security issues. ``` -kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/v1beta1/kubectl/kubectl-deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/master/kubectl/rbac/clusterrole.yaml ``` -## Install ClusterRole -**CAUTION:** The `clusterrole.yaml` is just a sample, should be modified based on real requirements to avoid potential security issues. +## Install ClusterRolebinding ``` -kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/v1beta1/kubectl/clusterrole.yaml +kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/master/kubectl/rbac/clusterrolebinding.yaml ``` -## Install ClusterRolebinding +## Install the Task ``` -kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/v1beta1/kubectl/clusterrolebinding.yaml +kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/master/kubectl/kubectl-deploy.yaml ``` -## Inputs +## Inputs ### Parameters -* **action**: The action to perform to the resource, support `get`, `create`, `apply`, `delete`, `replace`, `patch`. -* **manifest**: The content of the resource to deploy. -* **success-condition/failure-condition**: SuccessCondition and failureCondition are optional expressions which are evaluated upon every update of the resource. If failureCondition is ever evaluated to true, the step is considered failed. Likewise, if successCondition is ever evaluated to true the step is considered successful. It uses kubernetes label selection syntax and can be applied against any field of the resource (not just labels). Multiple AND conditions can be represented by comma delimited expressions. For more details, see: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/. -* **merge-strategy**: The strategy used to merge a patch, defaults to `strategic`, supported `strategic`, `merge` and `json`. -* **output**: Extracted from fields of the resource, only support jsonpath. Should define as a `yaml` array(array even if only one item): -``` - - name: output - value: | - - name: job-name - valueFrom: '{.metadata.name}' - - name: job-namespace - valueFrom: '{.metadata.namespace}' +- **action**: The action to perform to the resource, support `get`, `create`, `apply`, `delete`, `replace`, `patch`. +- **manifest**: The content of the resource to deploy. +- **success-condition/failure-condition**: SuccessCondition and failureCondition are optional expressions which are evaluated upon every update of the resource. If failureCondition is ever evaluated to true, the step is considered failed. Likewise, if successCondition is ever evaluated to true the step is considered successful. It uses kubernetes label selection syntax and can be applied against any field of the resource (not just labels). Multiple AND conditions can be represented by comma delimited expressions. For more details, see: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/. +- **merge-strategy**: The strategy used to merge a patch, defaults to `strategic`, supported `strategic`, `merge` and `json`. +- **output**: Extracted from fields of the resource, only support jsonpath. Should define as a `yaml` array(array even if only one item): + +```yaml +- name: output + value: | + - name: job-name + valueFrom: '{.metadata.name}' + - name: job-namespace + valueFrom: '{.metadata.namespace}' ``` + The extracted value will be write to`/tekton/results/$(name)`. -* **set-ownerreference**: Set the `ownerReferences` for the resource as pod of `step`, default to false. +- **set-ownerreference**: Set the `ownerReferences` for the resource as pod of `step`, default to false. ## Usage This TaskRun runs the Task to deploy the given Kubernetes resource. -``` +```yaml apiVersion: tekton.dev/v1beta1 kind: TaskRun metadata: @@ -56,31 +61,129 @@ spec: taskRef: name: kubectl-deploy-pod params: - - name: action - value: create - - name: success-condition - value: status.phase == Running - - name: failure-condition - value: status.phase in (Failed, Error) - - name: output - value: | - - name: job-name - valueFrom: '{.metadata.name}' - - name: job-namespace - valueFrom: '{.metadata.namespace}' - - name: set-ownerreference - value: "true" - - name: manifest - value: | - apiVersion: v1 - kind: Pod - metadata: - generateName: myapp-pod- - labels: - app: myapp - spec: - containers: - - name: myapp-container - image: docker - command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 30'] + - name: action + value: create + - name: success-condition + value: status.phase == Running + - name: failure-condition + value: status.phase in (Failed, Error) + - name: output + value: | + - name: job-name + valueFrom: '{.metadata.name}' + - name: job-namespace + valueFrom: '{.metadata.namespace}' + - name: set-ownerreference + value: "true" + - name: manifest + value: | + apiVersion: v1 + kind: Pod + metadata: + generateName: myapp-pod- + labels: + app: myapp + spec: + containers: + - name: myapp-container + image: docker + command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 30'] +``` + +# `kubectl-actions` + +This is a generic task used to perform kubernetes actions such as `kubectl get deployment` or `kubectl create -f filename.yaml`. For more commands [see](https://kubernetes.io/docs/reference/kubectl/overview/). + +## Install the task + +``` +kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/master/kubectl/kubectl-actions.yaml +``` + +## Inputs + +### Parameters + +- **script**: script of `kubectl` commands to execute e.g. `kubectl get pod $1 -0 yaml`. This will take the first value of ARGS as pod name (_default_: `kubectl $@`) +- **args**: args to execute which are appended to `kubectl` e.g. `start-build myapp` (_default_: `help`) +- **image**: Default image being `gcr.io/cloud-builders/kubectl`. If somebody wants to use their own image then they can provide it as a part of params. For example an image avilable is `lachlanevenson/k8s-kubectl` + +### Workspaces + +- **kubeconfig-dir**: If you want to deploy you application to another cluster then you can mount your `kubeconfig` file via this `workspace`. (Default: _emptyDir:{}_ in case `kubeconfig` is not mounted) +- **manifest-dir**: Manifest files can be provided via the workspaces.(Default: _emptyDir:{}_ in case no manifest is provided) + +## Usage + +In case no manifests are mounted + +```yaml +apiVersion: tekton.dev/v1beta1 +kind: TaskRun +metadata: + name: kubectl-run +spec: + taskRef: + name: kubectl-actions + params: + - name: SCRIPT + value: | + kubectl get pods + echo "-----------" + kubectl get deploy + workspaces: + - name: kubeconfig-dir + emptyDir: {} + - name: manifest-dir + emptyDir: {} +``` + +In case manifest is present on `GitHub` : + +```yaml +apiVersion: tekton.dev/v1beta1 +kind: TaskRun +metadata: + name: kubectl-run +spec: + taskRef: + name: kubectl-actions + params: + - name: script + value: | + kubectl apply -f https://raw.githubusercontent.com/vinamra28/social-client/master/k8s/deployment.yaml + ---------- + kubectl get deployment + workspaces: + - name: kubeconfig-dir + emptyDir: {} + - name: manifest-dir + emptyDir: {} +``` + +## Kubectl Patch Deployment Image + +If you have existing deployment and after period of time image of the application is being updated. So to update the container image in the deployment, this task can be used as this task will patch the image with the new image in the existing deployment. + +### Installing the Task + +``` +kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/master/kubectl/kubectl-update-deployment-image.yaml +``` + +## Usage + +```yaml +apiVersion: tekton.dev/v1beta1 +kind: TaskRun +metadata: + name: update-deployment-run +spec: + taskRef: + name: update-deployment + params: + - name: REPLACEMENT_IMAGE + value: quay.io/vinamra2807/social-client:v2 + - name: DEPLOYMENT_NAME + value: my-client-v1 ``` diff --git a/kubectl/examples/kubectl-actions-run.yaml b/kubectl/examples/kubectl-actions-run.yaml new file mode 100644 index 0000000000..cace839911 --- /dev/null +++ b/kubectl/examples/kubectl-actions-run.yaml @@ -0,0 +1,18 @@ +uapiVersion: tekton.dev/v1beta1 +kind: TaskRun +metadata: + name: kubectl-run +spec: + taskRef: + name: kubectl-actions + params: + - name: script + value: | + kubectl get pods + echo "---------" + kubectl get deploy + workspaces: + - name: kubeconfig-dir + emptyDir: {} + - name: manifest-dir + emptyDir: {} diff --git a/kubectl/taskrun-delete.yaml b/kubectl/examples/taskrun-delete.yaml similarity index 100% rename from kubectl/taskrun-delete.yaml rename to kubectl/examples/taskrun-delete.yaml diff --git a/kubectl/taskrun.yaml b/kubectl/examples/taskrun.yaml similarity index 100% rename from kubectl/taskrun.yaml rename to kubectl/examples/taskrun.yaml diff --git a/kubectl/kubectl-actions.yaml b/kubectl/kubectl-actions.yaml new file mode 100644 index 0000000000..079706b158 --- /dev/null +++ b/kubectl/kubectl-actions.yaml @@ -0,0 +1,36 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: kubectl-actions +spec: + workspaces: + - name: manifest-dir + - name: kubeconfig-dir + params: + - name: script + description: The Kubernetes CLI script to run + type: string + default: "kubectl $@" + - name: args + description: The Kubernetes CLI arguments to run + type: array + default: + - "help" + - name: image + default: gcr.io/cloud-builders/kubectl #image is huge + description: Kubectl wrapper image + steps: + - name: kubectl + image: $(params.image) + workingDir: $(workspaces.manifest-dir.path) + script: | + #!/usr/bin/env bash + + if [[ -f $(workspaces.kubeconfig-dir.path)/kubeconfig ]]; then + export KUBECONFIG=$(workspaces.kubeconfig-dir.path)/kubeconfig + fi + + $(params.script) + + args: + - "$(params.args)" diff --git a/kubectl/kubectl-update-deployment-image.yaml b/kubectl/kubectl-update-deployment-image.yaml new file mode 100644 index 0000000000..0a50f43865 --- /dev/null +++ b/kubectl/kubectl-update-deployment-image.yaml @@ -0,0 +1,26 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: kubectl-update-deployment-image +spec: + params: + - name: BASE_IMAGE + default: gcr.io/cloud-builders/kubectl + description: The base image for the task. + type: string + - name: REPLACEMENT_IMAGE + description: The name of the image that needs to be replaced. + type: string + - name: DEPLOYMENT_NAME + description: The name of the deployment in which image needs to be replaced. + type: string + steps: + - name: patch-image + image: $(params.BASE_IMAGE) + script: | + kubectl patch deployment $(params.DEPLOYMENT_NAME) --patch='{"spec":{"template":{"spec":{ + "containers":[{ + "name": "$(params.DEPLOYMENT_NAME)", + "image":"$(params.REPLACEMENT_IMAGE)" + }] + }}}}' diff --git a/kubectl/clusterrole.yaml b/kubectl/rbac/clusterrole.yaml similarity index 100% rename from kubectl/clusterrole.yaml rename to kubectl/rbac/clusterrole.yaml diff --git a/kubectl/clusterrolebinding.yaml b/kubectl/rbac/clusterrolebinding.yaml similarity index 100% rename from kubectl/clusterrolebinding.yaml rename to kubectl/rbac/clusterrolebinding.yaml