diff --git a/config.yaml b/config.yaml index 838e11c..ea40ccb 100644 --- a/config.yaml +++ b/config.yaml @@ -96,13 +96,15 @@ params: sidebar_menu_truncate: 1000 sidebar_search_disable: false url_latest_version: https://lifecycle.keptn.sh - version: 0.5.0 + version: v0.6.0 version_menu: Releases versions: - url: /docs-0.5.0/ version: 0.5.0 - url: /docs-0.4.1/ version: 0.4.1 + - url: /docs-v0.6.0/ + version: v0.6.0 - url: /docs-dev/ version: dev permalinks: blog = "/:section/:year/:month/:day/:slug/" diff --git a/content/en/docs-v0.6.0/_index.md b/content/en/docs-v0.6.0/_index.md new file mode 100644 index 0000000..7b1a7b7 --- /dev/null +++ b/content/en/docs-v0.6.0/_index.md @@ -0,0 +1,9 @@ +--- +title: Docs +linktitle: Docs +description: Learn how to use Keptn. +cascade: + type: docs + github_subdir: "docs/content/en/docs" + path_base_for_github_subdir: "/content/en/docs-dev" +--- \ No newline at end of file diff --git a/content/en/docs-v0.6.0/concepts/_index.md b/content/en/docs-v0.6.0/concepts/_index.md new file mode 100644 index 0000000..fd215f1 --- /dev/null +++ b/content/en/docs-v0.6.0/concepts/_index.md @@ -0,0 +1,8 @@ +--- +title: Concepts +description: Learn about underlying concepts of the keptn lifecycle toolkit. +icon: concepts +layout: quickstart +weight: 50 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- diff --git a/content/en/docs-v0.6.0/concepts/apps/_index.md b/content/en/docs-v0.6.0/concepts/apps/_index.md new file mode 100644 index 0000000..8600d42 --- /dev/null +++ b/content/en/docs-v0.6.0/concepts/apps/_index.md @@ -0,0 +1,34 @@ +--- +title: Apps +description: Learn what Keptn Apps are and how to use them +icon: concepts +layout: quickstart +weight: 10 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- + +An App contains information about all workloads and checks associated with an application. +It will use the following structure for the specification of the pre/post deployment and pre/post evaluations checks +that should be executed at app level: + +```yaml +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnApp +metadata: + name: podtato-head + namespace: podtato-kubectl +spec: + version: "1.3" + workloads: + - name: podtato-head-left-arm + version: 0.1.0 + - name: podtato-head-left-leg + version: 1.2.3 + postDeploymentTasks: + - post-deployment-hello + preDeploymentEvaluations: + - my-prometheus-definition +``` + +While changes in the workload version will affect only workload checks, a change in the app version will also cause a +new execution of app level checks. diff --git a/content/en/docs-v0.6.0/concepts/architecture/_index.md b/content/en/docs-v0.6.0/concepts/architecture/_index.md new file mode 100644 index 0000000..c0460ce --- /dev/null +++ b/content/en/docs-v0.6.0/concepts/architecture/_index.md @@ -0,0 +1,10 @@ +--- +title: Architecture +linktitle: Architecture +description: Understand the details of how Keptn Lifecycle Toolkit works +weight: 80 +cascade: + github_subdir: "docs/content/en/docs" + path_base_for_github_subdir: "/content/en/docs-dev" +--- + diff --git a/content/en/docs-v0.6.0/concepts/evaluations/_index.md b/content/en/docs-v0.6.0/concepts/evaluations/_index.md new file mode 100644 index 0000000..fd4887d --- /dev/null +++ b/content/en/docs-v0.6.0/concepts/evaluations/_index.md @@ -0,0 +1,49 @@ +--- +title: Evaluations +description: Learn what Keptn Evaluations are and how to use them +icon: concepts +layout: quickstart +weight: 10 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- + + +### Keptn Evaluation Definition + +A `KeptnEvaluationDefinition` is a CRD used to define evaluation tasks that can be run by the Keptn Lifecycle Toolkit +as part of pre- and post-analysis phases of a workload or application. + +A Keptn evaluation definition looks like the following: + +```yaml +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnEvaluationDefinition +metadata: + name: my-prometheus-evaluation +spec: + source: prometheus + objectives: + - name: query-1 + query: "xxxx" + evaluationTarget: <20 + - name: query-2 + query: "yyyy" + evaluationTarget: >4 +``` + +### Keptn Evaluation Provider + +A `KeptnEvaluationProvider` is a CRD used to define evaluation provider, which will provide data for the +pre- and post-analysis phases of a workload or application. + +A Keptn evaluation provider looks like the following: + +```yaml +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnEvaluationProvider +metadata: + name: prometheus +spec: + targetServer: "http://prometheus-k8s.monitoring.svc.cluster.local:9090" + secretName: prometheusLoginCredentials +``` diff --git a/content/en/docs-v0.6.0/concepts/metrics/_index.md b/content/en/docs-v0.6.0/concepts/metrics/_index.md new file mode 100644 index 0000000..66e4c44 --- /dev/null +++ b/content/en/docs-v0.6.0/concepts/metrics/_index.md @@ -0,0 +1,142 @@ +--- +title: Metrics +description: Learn what Keptn Metrics are and how to use them +icon: concepts +layout: quickstart +weight: 10 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- + +### Keptn Metric + +A `KeptnMetric` is a CRD representing a metric. The metric will be collected from the provider specified in the +specs.provider.name field. The query is a string in the provider-specific query language, used to obtain a metric. +Providing the metrics as CRD into a K8s cluster will facilitate the reusability of this data across multiple components. +Furthermore, this allows using multiple observability platforms for different metrics. Please note, there is a +limitation that `KeptnMetric` resource needs to be created only in `keptn-lifecycle-toolkit-system` namespace. + +A `KeptnMetric` looks like the following: + +```yaml +apiVersion: metrics.keptn.sh/v1alpha1 +kind: KeptnMetric +metadata: + name: keptnmetric-sample + namespace: keptn-lifecycle-toolkit-system +spec: + provider: + name: "" + query: "sum(kube_pod_container_resource_limits{resource='cpu'})" + fetchIntervalSeconds: 5 +``` + +Keptn metrics can be exposed as OTel metrics via port `9999` of the KLT operator. To expose them, the env +variable `EXPOSE_KEPTN_METRICS` in the operator manifest needs to be set to `true`. The default value of this variable +is `true`. To access the metrics, use the following command: + +```shell +kubectl port-forward deployment/klc-controller-manager 9999 -n keptn-lifecycle-toolkit-system +``` + +and access the metrics via your browser with: + +```http://localhost:9999/metrics``` + +#### Accessing Metrics via the Kubernetes Custom Metrics API + +`KeptnMetrics` that are located in the `keptn-lifecycle-toolkit-system` namespace can also be retrieved via the +Kubernetes Custom Metrics API. +This makes it possible to refer to these metrics via the Kubernetes *HorizontalPodAutoscaler*, as in the following +example: + +```yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: podtato-head-entry + namespace: podtato-kubectl +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: podtato-head-entry + minReplicas: 1 + maxReplicas: 10 + metrics: + - type: Object + object: + metric: + name: keptnmetric-sample + describedObject: + apiVersion: metrics.keptn.sh/v1alpha1 + kind: KeptnMetric + name: keptnmetric-sample + target: + type: Value + value: "10" +``` + +You can also use the `kubectl raw` command to retrieve the values of a `KeptnMetric`, as in the following example: + +```shell +$ kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta2/namespaces/podtato-kubectl/keptnmetrics.metrics.sh/keptnmetric-sample/keptnmetric-sample" | jq . + +{ + "kind": "MetricValueList", + "apiVersion": "custom.metrics.k8s.io/v1beta2", + "metadata": {}, + "items": [ + { + "describedObject": { + "kind": "KeptnMetric", + "namespace": "keptn-lifecycle-toolkit-system", + "name": "keptnmetric-sample", + "apiVersion": "metrics.keptn.sh/v1alpha1" + }, + "metric": { + "name": "keptnmetric-sample", + "selector": { + "matchLabels": { + "app": "frontend" + } + } + }, + "timestamp": "2023-01-25T09:26:15Z", + "value": "10" + } + ] +} +``` + +You can also filter based on matching labels. So to e.g. retrieve all metrics that are labelled with `app=frontend`, you +can use the following command: + +```shell +$ kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta2/namespaces/podtato-kubectl/keptnmetrics.metrics.sh/*/*?labelSelector=app%3Dfrontend" | jq . + +{ + "kind": "MetricValueList", + "apiVersion": "custom.metrics.k8s.io/v1beta2", + "metadata": {}, + "items": [ + { + "describedObject": { + "kind": "KeptnMetric", + "namespace": "keptn-lifecycle-toolkit-system", + "name": "keptnmetric-sample", + "apiVersion": "metrics.keptn.sh/v1alpha1" + }, + "metric": { + "name": "keptnmetric-sample", + "selector": { + "matchLabels": { + "app": "frontend" + } + } + }, + "timestamp": "2023-01-25T09:26:15Z", + "value": "10" + } + ] +} +``` diff --git a/content/en/docs-v0.6.0/concepts/overview/_index.md b/content/en/docs-v0.6.0/concepts/overview/_index.md new file mode 100644 index 0000000..4438e46 --- /dev/null +++ b/content/en/docs-v0.6.0/concepts/overview/_index.md @@ -0,0 +1,7 @@ +--- +title: Overview +icon: concepts +layout: quickstart +weight: 5 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- diff --git a/content/en/docs-v0.6.0/concepts/overview/how-it-works/_index.md b/content/en/docs-v0.6.0/concepts/overview/how-it-works/_index.md new file mode 100644 index 0000000..ab84523 --- /dev/null +++ b/content/en/docs-v0.6.0/concepts/overview/how-it-works/_index.md @@ -0,0 +1,7 @@ +--- +title: How it works +icon: concepts +layout: quickstart +weight: 5 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- \ No newline at end of file diff --git a/content/en/docs-v0.6.0/concepts/overview/klc-cert-manager/_index.md b/content/en/docs-v0.6.0/concepts/overview/klc-cert-manager/_index.md new file mode 100644 index 0000000..b76c12d --- /dev/null +++ b/content/en/docs-v0.6.0/concepts/overview/klc-cert-manager/_index.md @@ -0,0 +1,24 @@ +--- +title: Keptn Certificate Manager +icon: concepts +layout: quickstart +weight: 5 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- + +### Keptn Cert Manager + +The Lifecycle Toolkit includes a Mutating Webhook which requires TLS certificates to be mounted as a volume in its pod. +In version 0.6.0 and later, the certificate creation +is handled automatically by +the [klt-cert-manager](https://github.com/keptn/lifecycle-toolkit/blob/main/klt-cert-manager/README.md). + +The certificate is created as a secret in the `keptn-lifecycle-toolkit-system` namespace with a renewal threshold of 12 +hours. +If it expires, the [klt-cert-manager](https://github.com/keptn/lifecycle-toolkit/blob/main/klt-cert-manager/README.md) +renews it. +The Lifecycle Toolkit operator waits for a valid certificate to be ready. +The certificate is mounted on an empty dir volume in the operator. + +When a certificate is left over from an older version, the webhook or the operator may generate errors because of an +invalid certificate. To solve this, delete the certificate and restart the operator. diff --git a/content/en/docs-v0.6.0/concepts/overview/phases/_index.md b/content/en/docs-v0.6.0/concepts/overview/phases/_index.md new file mode 100644 index 0000000..2796f5c --- /dev/null +++ b/content/en/docs-v0.6.0/concepts/overview/phases/_index.md @@ -0,0 +1,7 @@ +--- +title: Phases +icon: concepts +layout: quickstart +weight: 10 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- diff --git a/content/en/docs-v0.6.0/concepts/tasks/_index.md b/content/en/docs-v0.6.0/concepts/tasks/_index.md new file mode 100644 index 0000000..f7236be --- /dev/null +++ b/content/en/docs-v0.6.0/concepts/tasks/_index.md @@ -0,0 +1,172 @@ +--- +title: Tasks +description: Learn what Keptn Tasks are and how to use them +icon: concepts +layout: quickstart +weight: 10 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- + +### Keptn Task Definition + +A `KeptnTaskDefinition` is a CRD used to define tasks that can be run by the Keptn Lifecycle Toolkit +as part of pre- and post-deployment phases of a deployment. +The task definition is a [Deno](https://deno.land/) script +Please, refer to the [function runtime](https://github.com/keptn/lifecycle-toolkit/tree/main/functions-runtime) for more +information about the runtime. +In the future, we also intend to support other runtimes, especially running a container image directly. + +A task definition can be configured in three different ways: + +- inline +- referring to an HTTP script +- referring to another `KeptnTaskDefinition` + +An inline task definition looks like the following: + +```yaml +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnTaskDefinition +metadata: + name: deployment-hello +spec: + function: + inline: + code: | + console.log("Deployment Task has been executed"); +``` + +In the code section, it is possible to define a full-fletched Deno script. + +```yaml +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnTaskDefinition +metadata: + name: hello-keptn-inline +spec: + function: + inline: + code: | + let text = Deno.env.get("DATA"); + let data; + let name; + data = JSON.parse(text); + + name = data.name + console.log("Hello, " + name + " new"); +``` + +The runtime can also fetch the script on the fly from a remote webserver. For this, the CRD should look like the +following: + +```yaml +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnTaskDefinition +metadata: + name: hello-keptn-http +spec: + function: + httpRef: + url: +``` + +An example is +available [here](https://github.com/keptn-sandbox/lifecycle-toolkit-examples/blob/main/sample-app/version-1/app-pre-deploy.yaml) +. + +Finally, `KeptnTaskDefinition` can build on top of other `KeptnTaskDefinition`s. +This is a common use case where a general function can be re-used in multiple places with different parameters. + +```yaml +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnTaskDefinition +metadata: + name: slack-notification-dev +spec: + function: + functionRef: + name: slack-notification + parameters: + map: + textMessage: "This is my configuration" + secureParameters: + secret: slack-token +``` + +## Context + +A context environment variable is available via `Deno.env.get("CONTEXT")`. It can be used like this: + +```javascript +let context = Deno.env.get("CONTEXT"); + +if (contextdata.objectType == "Application") { + let application_name = contextdata.appName; + let application_version = contextdata.appVersion; +} + +if (contextdata.objectType == "Workload") { + let application_name = contextdata.appName; + let workload_name = contextdata.workloadName; + let workload_version = contextdata.workloadVersion; +} +``` + +## Input Parameters and Secret Handling + +As you might have noticed, Task Definitions also have the possibility to use input parameters. +The Lifecycle Toolkit passes the values defined inside the `map` field as a JSON object. +At the moment, multi-level maps are not supported. +The JSON object can be read through the environment variable `DATA` using `Deno.env.get("DATA");`. +K8s secrets can also be passed to the function using the `secureParameters` field. +Currently only one secret can be passed. The secret must have a `key` called `SECURE_DATA`. +It can be accessed via the environment variable `Deno.env.get("SECURE_DATA")`. + +For example: + +```yaml +# kubectl create secret generic my-secret --from-literal=SECURE_DATA=foo + +apiVersion: lifecycle.keptn.sh/v1alpha1 +kind: KeptnTaskDefinition +metadata: + name: dummy-task + namespace: "default" +spec: + function: + secureParameters: + secret: my-secret + inline: + code: | + let secret_text = Deno.env.get("SECURE_DATA"); + // secret_text = "foo" +``` + +This methodology supports multiple variables by creating a K8s secret with a JSON string: + +```yaml +# kubectl create secret generic my-secret \ +# --from-literal=SECURE_DATA="{\"foo\": \"bar\", \"foo2\": \"bar2\"}" + +apiVersion: lifecycle.keptn.sh/v1alpha1 +kind: KeptnTaskDefinition +metadata: + name: dummy-task + namespace: "default" +spec: + function: + secureParameters: + secret: my-secret + inline: + code: | + let secret_text = Deno.env.get("SECURE_DATA"); + let secret_text_obj = JSON.parse(secret_text); + // secret_text_obj["foo"] = "bar" + // secret_text_obj["foo2"] = "bar2" +``` + +### Keptn Task + +A Task is responsible for executing the TaskDefinition of a workload. +The execution is done spawning a K8s Job to handle a single Task. +In its state, it keeps track of the current status of the K8s Job created. diff --git a/content/en/docs-v0.6.0/concepts/workloads/_index.md b/content/en/docs-v0.6.0/concepts/workloads/_index.md new file mode 100644 index 0000000..78b1cb8 --- /dev/null +++ b/content/en/docs-v0.6.0/concepts/workloads/_index.md @@ -0,0 +1,24 @@ +--- +title: Workloads +description: Learn what Keptn Workloads are and how to use them +icon: concepts +layout: quickstart +weight: 10 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- + +A Workload contains information about which tasks should be performed during the `preDeployment` as well as +the `postDeployment` +phase of a deployment. In its state it keeps track of the currently active `Workload Instances`, which are responsible +for doing those checks for +a particular instance of a Deployment/StatefulSet/ReplicaSet (e.g. a Deployment of a certain version). + +### Keptn Workload Instance + +A Workload Instance is responsible for executing the pre- and post deployment checks of a workload. In its state, it +keeps track of the current status of all checks, as well as the overall state of +the Pre Deployment phase, which can be used by the scheduler to tell that a pod can be allowed to be placed on a node. +Workload Instances have a reference to the respective Deployment/StatefulSet/ReplicaSet, to check if it has reached the +desired state. If it detects that the referenced object has reached +its desired state (e.g. all pods of a deployment are up and running), it will be able to tell that +a `PostDeploymentCheck` can be triggered. diff --git a/content/en/docs-v0.6.0/crd-ref/_index.md b/content/en/docs-v0.6.0/crd-ref/_index.md new file mode 100644 index 0000000..f4271ed --- /dev/null +++ b/content/en/docs-v0.6.0/crd-ref/_index.md @@ -0,0 +1,15 @@ +--- +title: CRD Reference pages +description: Reference information about the KLT CRDs +weight: 100 +hidechildren: false # this flag hides all sub-pages in the sidebar-multicard.html +--- + +This section provides comprehensive reference information about the +[Custom Resource Definitions (CRDs)](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) +that are defined for the Keptn Lifecycle Toolkit. + +**NOTE: This section is under development. +Information that is published here has been reviewed for technical accuracy +but the format and content is still evolving. +We welcome your input!** diff --git a/content/en/docs-v0.6.0/crd-ref/crd-template.md b/content/en/docs-v0.6.0/crd-ref/crd-template.md new file mode 100644 index 0000000..d5dcec6 --- /dev/null +++ b/content/en/docs-v0.6.0/crd-ref/crd-template.md @@ -0,0 +1,32 @@ +--- +title: +description: +weight: +hide: true +--- + +Copy this template to create a new CRD reference page. + +1. Replace the variable text in metadata with information for this page +1. Delete the `hidden: true` line +1. Delete these instructions from your file +1. Populate the page with appropriate content + +## Synopsis + +## Parameters + + + +## Usage + + + + +## Examples + +## Files + +## Differences between versions + +## See also diff --git a/content/en/docs-v0.6.0/getting-started.md b/content/en/docs-v0.6.0/getting-started.md new file mode 100644 index 0000000..ef7e788 --- /dev/null +++ b/content/en/docs-v0.6.0/getting-started.md @@ -0,0 +1,197 @@ +--- +title: Getting Started +linktitle: Getting Started +description: Learn how to use the Keptn Lifecycle Toolkit. +weight: 15 +cascade: +github_subdir: "docs/content/en/docs" +path_base_for_github_subdir: "/content/en/docs-dev" +--- + +`kubectl create -f deployment.yaml` will "blindly" deploy workloads, but who needs to be notified that this deployment +is about to happen? Is your infrastructure ready? Do your downstream services meet their SLOs? Can your infrastructure +handle the deployment? + +After the deployment, beyond the standard k8s probes, how can you integrate with other tooling to automatically test the +deployment? How do you know the deployment is meeting its SLOs? Has the deployment caused any issues downstream? Who +needs to know that the deployment was successful (or unsuccessful)? + +The Keptn Lifecycle Toolkit (KLT) "wraps" a standard Kubernetes deployment and provides both workload (single service) +tests and SLO evaluations. Multiple workloads can also be logically grouped (and evaluated) as a single cohesive unit: a +Keptn Application. In other words, an application is a collection of multiple workloads. + +The Keptn Lifecycle Toolkit is a tool and vendor-neutral mechanism - it does not depend on particular GitOps tooling - +ArgoCD, Flux, Gitlab or others - KLT works with them all. + +The Keptn Lifecycle Toolkit emits signals at every stage (k8s events, OpenTelemetry metrics and traces) to ensure your +deployments are observable. + +Available steps (applicable to both workload and application entities): + +* Pre-Deployment Tasks: e.g. checking for dependant services, checking if the cluster is ready for the deployment, etc. +* Pre-Deployment Evaluations: e.g. evaluate metrics before your application gets deployed (e.g. layout of the cluster) +* Post-Deployment Tasks: e.g. trigger a test, trigger a deployment to another cluster, etc. +* Post-Deployment Evaluations: e.g. evaluate the deployment, evaluate the test results, etc. + +## What you will learn here + +* Use the Keptn Lifecycle Toolkit to control the deployment of your application +* Connect the lifecycle-toolkit to Prometheus +* Use pre-deployment tasks to check if a dependency is met before deploying a workload +* Use post-deployment tasks on an application level to send a notification + +## Prerequisites + +* A Kubernetes cluster >= Kubernetes 1.24 + * If you don't have one, we recommend [Kubernetes-in-Docker(KinD)](https://kind.sigs.k8s.io/docs/user/quick-start/) + to set up your local development environment +* kubectl installed on your system + * See () for more information + +## Check Kubernetes Version + +Run the following and ensure both client and server versions are greater than or equal to v1.24. + +```shell +kubectl version --short +``` + +The output should look like this. In this example, both client and server are at v1.24.0 so the Keptn Lifecycle Toolkit +will work. + +{{% readfile file="./snippets/tasks/k8s_version_output.md" markdown="true" %}} + +## Install the Keptn Lifecycle Toolkit + +{{% readfile file="./snippets/tasks/install.md" markdown="true" %}} + +## Check out the Getting Started Repository + +For the further progress of this guide, we need a sample application as well as some helpers which make it easier for +your to set up your environment. These things can be found in our Getting Started repository which can be checked out as +follows: + +```shell +git clone https://github.com/keptn-sandbox/lifecycle-toolkit-examples.git +cd lifecycle-toolkit-examples +``` + +## Install the required observability features + +The Keptn Lifecycle Toolkit emits OpenTelemetry data as standard but the toolkit does not come pre-bundled with +Observability backend tooling. This is deliberate as it provides flexibility for you to bring your own Observability +backend which consumes this emitted data. + +In order to use the observability features of the lifecycle toolkit, we need a monitoring and tracing backend. + +In this guide, we will use [Prometheus](https://prometheus.io/) for Metrics, [Jaeger](https://jaegertracing.io) for +Traces and [Grafana](https://github.com/grafana/) for Dashboarding. + +```shell +make install-observability +make restart-lifecycle-toolkit +``` + +## The Demo Application + +For this demonstration, we use a slightly modified version +of [the PodTatoHead](https://github.com/podtato-head/podtato-head). + + +![img.png](assets/podtatohead.png) + +Over time, we will evolve this application from a simple manifest to a Keptn-managed application. We will install it +first with kubectl and add pre- as well as post-deployment tasks. For this, we will check if the entry service is +available before the other ones get scheduled. Afterward, we will add evaluations to ensure that our infrastructure is +in a good shape before we deploy the application. Finally, we will evolve to a GitOps driven deployment and will notify +an external webhook service when the deployment has finished. + +## Install the Demo Application (Version 1) + +In the first version of the Demo application, the Keptn Lifecycle Toolkit evaluates metrics provided by prometheus and +checks if a specified amount of CPUs is available before deploying the application + +To install it, simply apply the manifest: + +```shell +make deploy-version-1 +``` + +You can watch the progress of the deployment as follows: + +### Watch workload state + +When the Lifecycle Toolkit detects workload labels ("app.kubernetes.io/name" and "keptn.sh/workload") on a resource, a +KeptnWorkloadInstance (kwi) resource will be created. Using this resource you can watch the progress of the deployment. + +```shell +kubectl get keptnworkloadinstances -n podtato-kubectl +``` + +This will show the current status of the Workloads and in which phase they are at the moment. You can get more detailed +information about the workloads by describing one of the resources: + +```shell +kubectl describe keptnworkloadinstances podtato-head-podtato-head-entry -n podtato-kubectl +``` + +Note that there are more detailed information in the event stream of the object. + +### Watch application state + +Although you didn't specify an application in your manifest, the Lifecycle Toolkit assumed that this is a single-service +application and created an ApplicationVersion (kav) resource for you. + +Using `kubectl get keptnappversions -n podtato-kubectl` you can see state of these resources. + +### Watch pods + +Obviously, you should see that the pods are starting normally. You can watch the state of the pods using: + +```shell +kubectl get pods -n podtato-kubectl +``` + +Furthermore, you can port-forward the podtato-head service to your local machine and access the application via your +browser: + +```shell +make port-forward-grafana +``` + +In your browser (, Log in with the user 'admin' and the password 'admin'), you can open the +Dashboard `Keptn Applications` and see the current state of the application which should be similar to the following: + + +![grafana.png](assets/grafana.png) + +In this screen you get the following information: + +* Successful/Failed Deployments +* Time between Deployments +* Deployment Time per Version +* The link to the Trace of the deployment + +After some time (~60 seconds), you should see one more failed deployment in your dashboard. You can click on the link to +the trace and see the reason for the failure: + + +![trace-failed.png](assets/trace-failed.png) + +In this case, we see the name of the failed pre-deployment evaluation and the reason for the failure. In this case, the +minimum amount of CPUs is not met. This is a problem we can solve by changing the treshold in the evaluation file. + +## Install the Demo Application (Version 2) + +To achieve this, we changed the operator in the evaluation file (sample-app/version-2/app-pre-deploy-eval) from `<` +to `>` and applied the new manifest: + +```shell +kubectl apply -f sample-app/version-2 +``` + +After this, you can inspect the new state of the application using the same commands as before. You should see that the +deployment is now successful and that the trace is also updated. You should also see in the Grafana Dashboards that the +deployment was successful. + +Congratulations! You successfully deployed the first application using the Keptn Lifecycle Toolkit! diff --git a/content/en/docs-v0.6.0/getting-started/assets/grafana.png b/content/en/docs-v0.6.0/getting-started/assets/grafana.png new file mode 100644 index 0000000..730c03d Binary files /dev/null and b/content/en/docs-v0.6.0/getting-started/assets/grafana.png differ diff --git a/content/en/docs-v0.6.0/getting-started/assets/podtatohead.png b/content/en/docs-v0.6.0/getting-started/assets/podtatohead.png new file mode 100644 index 0000000..440d9d9 Binary files /dev/null and b/content/en/docs-v0.6.0/getting-started/assets/podtatohead.png differ diff --git a/content/en/docs-v0.6.0/getting-started/assets/trace-failed.png b/content/en/docs-v0.6.0/getting-started/assets/trace-failed.png new file mode 100644 index 0000000..99b3424 Binary files /dev/null and b/content/en/docs-v0.6.0/getting-started/assets/trace-failed.png differ diff --git a/content/en/docs-v0.6.0/snippets/tasks/install.md b/content/en/docs-v0.6.0/snippets/tasks/install.md new file mode 100644 index 0000000..1ddca96 --- /dev/null +++ b/content/en/docs-v0.6.0/snippets/tasks/install.md @@ -0,0 +1,32 @@ +# Installation Instructions + +## Install version 0.6.0 and above + +In version 0.6.0 and later, you can install the Lifecycle Toolkit using the current release manifest: + + + +```shell +kubectl apply -f https://github.com/keptn/lifecycle-toolkit/releases/download/v0.5.0/manifest.yaml +kubectl wait --for=condition=Available deployment/klc-controller-manager -n keptn-lifecycle-toolkit-system --timeout=120s +``` + + + +The Lifecycle Toolkit and its dependencies are now installed and ready to use. + +## Install version 0.5.0 and earlier + +You must first install *cert-manager* with the following commands: + +```shell +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml +kubectl wait --for=condition=Available deployment/cert-manager-webhook -n cert-manager --timeout=60s +``` + +After that, you can install the Lifecycle Toolkit `` with: + +```shell +kubectl apply -f https://github.com/keptn/lifecycle-toolkit/releases/download//manifest.yaml +kubectl wait --for=condition=Available deployment/klc-controller-manager -n keptn-lifecycle-toolkit-system --timeout=120s +``` diff --git a/content/en/docs-v0.6.0/snippets/tasks/k8s_version_output.md b/content/en/docs-v0.6.0/snippets/tasks/k8s_version_output.md new file mode 100644 index 0000000..eea156d --- /dev/null +++ b/content/en/docs-v0.6.0/snippets/tasks/k8s_version_output.md @@ -0,0 +1,9 @@ + +```shell +$ kubectl version --short +Flag --short has been deprecated, and will be removed in the future. The --short output will become the default. +Client Version: v1.24.0 +Kustomize Version: v4.5.4 +Server Version: v1.24.0 +``` + diff --git a/content/en/docs-v0.6.0/tasks/_index.md b/content/en/docs-v0.6.0/tasks/_index.md new file mode 100644 index 0000000..0c47832 --- /dev/null +++ b/content/en/docs-v0.6.0/tasks/_index.md @@ -0,0 +1,9 @@ +--- +title: Tasks +description: This section of the documentation describes how to do individual tasks with Keptn. +icon: concepts +layout: quickstart +weight: 40 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- + diff --git a/content/en/docs-v0.6.0/tasks/add-app-awareness/index.md b/content/en/docs-v0.6.0/tasks/add-app-awareness/index.md new file mode 100644 index 0000000..2534e3f --- /dev/null +++ b/content/en/docs-v0.6.0/tasks/add-app-awareness/index.md @@ -0,0 +1,119 @@ +# Add Application Awareness + +In the previous step, we installed the demo application without any application awareness. This means that the Lifecycle +Toolkit assumed that every workload is a single-service application at the moment and created the Application resources +for you. + +To get the overall state of an application, we need a grouping of workloads, called KeptnApp in the Lifecycle Toolkit. +To get this working, we need to modify our application manifest with two things: + +* Add an "app.kubernetes.io/part-of" or "keptn.sh/app" label to the deployment +* Create an application resource + +## Preparing the Manifest and create an App resource + +--- + +### TL;DR + +You can also used the prepared manifest and apply it directly using: `kubectl apply -k sample-app/version-2/` and +proceed [here](#watch-application-behavior). + +--- + +### Otherwise + +Create a temporary directory and copy the base manifest there: + +```shell +mkdir ./my-deployment +cp demo-application/base/manifest.yml ./my-deployment +``` + +Now, open the manifest in your favorite editor and add the following label to the deployments, e.g.: + +```yaml +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: podtato-head-right-leg + namespace: podtato-kubectl + labels: + app: podtato-head +spec: + selector: + matchLabels: + component: podtato-head-right-leg + template: + metadata: + labels: + component: podtato-head-right-leg + annotations: + keptn.sh/workload: "right-leg" + keptn.sh/version: "0.1.0" + keptn.sh/app: "podtato-head" + spec: + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: ghcr.io/podtato-head/right-leg:0.2.7 + imagePullPolicy: Always + ports: + - containerPort: 9000 + env: + - name: PODTATO_PORT + value: "9000" +``` + +Now, update the version of the workloads in the manifest to `0.2.0`. + +Finally, create an application resource (app.yaml) and save it in the directory as well: + +```yaml +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnApp +metadata: + name: podtato-head + namespace: podtato-kubectl +spec: + version: "0.1.0" + workloads: + - name: left-arm + version: "0.1.1" + - name: left-leg + version: "0.1.1" + - name: entry + version: "0.1.1" + - name: right-arm + version: "0.1.1" + - name: left-arm + version: "0.1.1" + - name: hat + version: "0.1.1" +``` + +Now, apply the manifests: + +```shell +kubectl apply -f ./my-deployment/. +``` + +## Watch Application behavior + +Now, your application gets deployed in an application aware way. This means that pre-deployment tasks and evaluations +would be executed if you would have any. The same would happen for post-deployment tasks and evaluations after the last +workload has been deployed successfully. + +Now that you defined your application, you could watch the state of the whole application using: + +```shell +kubectl get keptnappversions -n podtato-kubectl` +``` + +You should see that the application is in a progressing state as long as the workloads (`kubectl get kwi`) are +progressing. After the last application has been deployed, and post-deployment tasks and evaluations are finished (there +are none at this point), the state should switch to completed. + +Now, we have deployed an application and are able to get the total state of the application state. Metrics and traces +get exported and now we're ready to dive deeper in the world of Pre- and Post-Deployment Tasks. diff --git a/content/en/docs-v0.6.0/tasks/evaluate/_index.md b/content/en/docs-v0.6.0/tasks/evaluate/_index.md new file mode 100644 index 0000000..d6529b1 --- /dev/null +++ b/content/en/docs-v0.6.0/tasks/evaluate/_index.md @@ -0,0 +1,8 @@ +--- +title: Evaluate Metrics +description: Learn how to use the Keptn Lifecycle Toolkit and explore basic features. +icon: concepts +layout: quickstart +weight: 25 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- diff --git a/content/en/docs-v0.6.0/tasks/implement-slack-notification/_index.md b/content/en/docs-v0.6.0/tasks/implement-slack-notification/_index.md new file mode 100644 index 0000000..c77f37c --- /dev/null +++ b/content/en/docs-v0.6.0/tasks/implement-slack-notification/_index.md @@ -0,0 +1,39 @@ +--- +title: Implement Slack Notification +description: Learn how to implement Slack notification as a post deployment task. +icon: concepts +layout: quickstart +weight: 24 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- + +## Create Slack Webhook + +At first, create an incoming slack webhook. +Necessary information is available in the [slack api page](https://api.slack.com/messaging/webhooks). +Once you create the webhook, you will get a URL similar to below example. + +`https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX` + +`T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX` is the secret part of the webhook which we would need in the next step. + +## Create slack-secret + +Create a `slack-secret.yaml` definition using the following command. +This will create a kubernetes secret named `slack-secret.yaml` in the `examples/sample-app/base` directory. +Before running this command change your current directory into `examples/sample-app`. + +```shell +kubectl create secret generic slack-secret --from-literal=SECURE_DATA='{"slack_hook":,"text":"Deployed PodTatoHead Application"}' -n podtato-kubectl -oyaml --dry-run=client > base/slack-secret.yaml +``` + +## Enable post deployment task + +To enable Slack notification add `post-deployment-notification` in as a postDeploymentTasks in the +[examples/sample-app/base/app.yaml](https://github.com/keptn/lifecycle-toolkit/blob/main/examples/sample-app/base/app.yaml) +file as shown below. + +```yaml + postDeploymentTasks: + - post-deployment-notification +``` diff --git a/content/en/docs-v0.6.0/tasks/install/_index.md b/content/en/docs-v0.6.0/tasks/install/_index.md new file mode 100644 index 0000000..653c0c6 --- /dev/null +++ b/content/en/docs-v0.6.0/tasks/install/_index.md @@ -0,0 +1,10 @@ +--- +title: Install the Lifecycle Toolkit +description: Learn how to use the Keptn Lifecycle Toolkit and explore basic features. +icon: concepts +layout: quickstart +weight: 15 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- + +{{% readfile file="../../snippets/tasks/install.md" markdown="true" %}} diff --git a/content/en/docs-v0.6.0/tasks/restart-application-deployment/_index.md b/content/en/docs-v0.6.0/tasks/restart-application-deployment/_index.md new file mode 100644 index 0000000..2f005fe --- /dev/null +++ b/content/en/docs-v0.6.0/tasks/restart-application-deployment/_index.md @@ -0,0 +1,184 @@ +--- +title: Restart an Application Deployment +description: Learn how to restart an unsuccessful Keptn Application Deployment. +icon: concepts +layout: quickstart +weight: 20 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- + +## Restart an Application Deployment + +During the deployment of a `KeptnApp`, it might be that the deployment fails due to an unsuccessful pre-deployment +evaluation or pre-deployment task. +This could happen because of, e.g., a misconfigured target value of a `KeptnEvaluationDefinition`, or a wrong URL being +checked in a pre deployment check. + +To retry a `KeptnApp` deployment without incrementing the version of the `KeptnApp`, we introduced the concept of ** +revisions** for a `KeptnAppVersion`. This means that +whenever the spec of a `KeptnApp` changes, even though the version stays the same, the KLT Operator will create a new +revision of the `KeptnAppVersion` referring to the `KeptnApp`. + +This way, when a `KeptnApp` failed due to a misconfigured pre-deployment check, you can first fix the configuration of +the `KeptnTaskDefinition`/`KeptnEvaluationDefinition`, then +increase the value of `spec.revision` of the `KeptnApp` and finally apply the updated `KeptnApp` manifest. +This will result in a restart of the `KeptnApp`. +Afterwards, all related `KeptnWorkloadInstances` will automatically refer to the newly +created revision of the `KeptnAppVersion` to determine whether they are allowed to enter their respective deployment +phase. + +To illustrate this, let's have a look at the following example: + +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: restartable-apps + annotations: + keptn.sh/lifecycle-toolkit: "enabled" +--- +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnApp +metadata: + name: podtato-head + namespace: restartable-apps +spec: + version: "0.1.1" + revision: 1 + workloads: + - name: podtato-head-entry + version: "0.1.2" + preDeploymentTasks: + - pre-deployment-check +--- +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnTaskDefinition +metadata: + name: pre-deployment-check + namespace: restartable-apps +spec: + function: + inline: + code: | + console.error("I failed") + process.exit(1) +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: podtato-head-entry + namespace: restartable-apps + labels: + app: podtato-head +spec: + selector: + matchLabels: + component: podtato-head-entry + template: + metadata: + labels: + component: podtato-head-entry + keptn.sh/workload: podtato-head-entry + keptn.sh/app: podtato-head + keptn.sh/version: "0.1.2" + spec: + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: ghcr.io/podtato-head/entry:0.2.7 + imagePullPolicy: Always + ports: + - containerPort: 9000 + env: + - name: PODTATO_PORT + value: "9000" +``` + +In this example, the `KeptnApp` executes a pre-deployment check which clearly fails due to the `pre-deployment-check` +task, and will therefore not be able to proceed with the deployment. + +After applying this manifest, you can inspect the status of the created `KeptnAppVersion`: + +```shell +$ kubectl get keptnappversions.lifecycle.keptn.sh -n restartable-apps +NAME APPNAME VERSION PHASE +podtato-head-0.1.1-1 podtato-head 0.1.1 AppPreDeployTasks +``` + +You will notice that the `KeptnAppVersion` will stay in the `AppPreDeployTasks` phase for a while, due to the pre-check +trying to run until a certain failure threshold is reached. +Eventually, you will find the `KeptnAppVersion`'s `PredeploymentPhase` to be in a `Failed` state, with the remaining +phases being `Deprecated`. + + +```shell +$ kubectl get keptnappversions.lifecycle.keptn.sh -n restartable-apps -owide +NAME APPNAME VERSION PHASE PREDEPLOYMENTSTATUS PREDEPLOYMENTEVALUATIONSTATUS WORKLOADOVERALLSTATUS POSTDEPLOYMENTSTATUS POSTDEPLOYMENTEVALUATIONSTATUS +podtato-head-0.1.1-1 podtato-head 0.1.1 AppPreDeployTasks Failed Deprecated Deprecated Deprecated Deprecated +``` + + +Now, to fix the deployment of this application, we first need to fix the task that has failed earlier. +To do so, edit the `pre-deployment-check` `KeptnTaskDefinition` to the +following (`kubectl -n restartable-apps edit keptntaskdefinitions.lifecycle.keptn.sh pre-deployment-check`): + +```yaml +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnTaskDefinition +metadata: + name: pre-deployment-check + namespace: restartable-apps +spec: + function: + inline: + code: | + console.error("Success") +``` + +After we have done that, we can restart the deployment of our `KeptnApplication` by incrementing the `spec.revision` +field by one +(`kubectl -n restartable-apps edit keptnapps.lifecycle.keptn.sh podtato-head`): + +```yaml +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnApp +metadata: + name: podtato-head + namespace: restartable-apps +spec: + version: "0.1.1" + revision: 2 # Increased this value from 1 to 2 + workloads: + - name: podtato-head-entry + version: "0.1.2" + preDeploymentTasks: + - pre-deployment-check +``` + +After those changes have been made, you will notice a new revision of the `podtato-head` `KeptnAppVersion`: + +```shell +$ kubectl get keptnappversions.lifecycle.keptn.sh -n restartable-apps +NAME APPNAME VERSION PHASE +podtato-head-0.1.1-1 podtato-head 0.1.1 AppPreDeployTasks +podtato-head-0.1.1-2 podtato-head 0.1.1 AppDeploy +``` + +As you will see, the newly created revision `podtato-head-0.1.1-2` has made it beyond the pre-deployment check phase and +has reached its `AppDeployPhase`. + +You can also verify the execution of the `pre-deployment-check` by retrieving the list of `KeptnTasks` in +the `restartable-apps` namespace: + + +```shell +$ kubectl get keptntasks.lifecycle.keptn.sh -n restartable-apps +NAME APPNAME APPVERSION WORKLOADNAME WORKLOADVERSION JOB NAME STATUS +pre-pre-deployment-check-49827 podtato-head 0.1.1 klc-pre-pre-deployment-check--77601 Failed +pre-pre-deployment-check-65056 podtato-head 0.1.1 klc-pre-pre-deployment-check--57313 Succeeded +``` + + +You will notice that for both the `KeptnAppVersions` and `KeptnTasks` the previous failed instances are still available, +as this might be useful historical data to keep track of +what went wrong during earlier deployment attempts. diff --git a/content/en/docs-v0.6.0/tasks/write-tasks/_index.md b/content/en/docs-v0.6.0/tasks/write-tasks/_index.md new file mode 100644 index 0000000..6fdc7e5 --- /dev/null +++ b/content/en/docs-v0.6.0/tasks/write-tasks/_index.md @@ -0,0 +1,77 @@ +--- +title: Write Keptn Tasks +description: Learn how to use the Keptn Lifecycle Toolkit and explore basic features. +icon: concepts +layout: quickstart +weight: 20 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- + +## Keptn Task Definition + +A `KeptnTaskDefinition` is a CRD used to define tasks that can be run by the Keptn Lifecycle Toolkit +as part of pre- and post-deployment phases of a deployment. The task definition is a [Deno](https://deno.land/) script. +In the future, we also intend to support other runtimes, especially running a container image directly. + +A task definition can be configured in three different ways: + +- inline +- referring to an HTTP script +- referring to another `KeptnTaskDefinition` + +An inline task definition looks like the following: + +```yaml +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnTaskDefinition +metadata: + name: deployment-hello +spec: + function: + inline: + code: | + console.log("Deployment Task has been executed"); +``` + +In the code section, it is possible to define a full-fletched Deno script. + +The runtime can also fetch the script on the fly from a remote webserver. For this, the CRD should look like the +following: + +```yaml +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnTaskDefinition +metadata: + name: hello-keptn-http +spec: + function: + httpRef: + url: +``` + +Finally, `KeptnTaskDefinition` can build on top of other `KeptnTaskDefinition`s. +This is a common use case where a general function can be re-used in multiple places with different parameters. + +```yaml +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnTaskDefinition +metadata: + name: slack-notification-dev +spec: + function: + functionRef: + name: slack-notification + parameters: + map: + textMessage: "This is my configuration" + secureParameters: + secret: slack-token +``` + +As you might have noticed, Task Definitions also have the possibility to use input parameters. +The Lifecycle Toolkit passes the values defined inside the `map` field as a JSON object. +At the moment, multi-level maps are not supported. +The JSON object can be read through the environment variable `DATA` using `Deno.env.get("DATA");`. +Kubernetes secrets can also be passed to the function using the `secureParameters` field. +Here, the `secret` value is the K8s secret name that will be mounted into the runtime and made available to the function +via the environment variable `SECURE_DATA`. diff --git a/content/en/docs/concepts/architecture/_index.md b/content/en/docs/concepts/architecture/_index.md new file mode 100644 index 0000000..c0460ce --- /dev/null +++ b/content/en/docs/concepts/architecture/_index.md @@ -0,0 +1,10 @@ +--- +title: Architecture +linktitle: Architecture +description: Understand the details of how Keptn Lifecycle Toolkit works +weight: 80 +cascade: + github_subdir: "docs/content/en/docs" + path_base_for_github_subdir: "/content/en/docs-dev" +--- + diff --git a/content/en/docs/concepts/metrics/_index.md b/content/en/docs/concepts/metrics/_index.md new file mode 100644 index 0000000..66e4c44 --- /dev/null +++ b/content/en/docs/concepts/metrics/_index.md @@ -0,0 +1,142 @@ +--- +title: Metrics +description: Learn what Keptn Metrics are and how to use them +icon: concepts +layout: quickstart +weight: 10 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- + +### Keptn Metric + +A `KeptnMetric` is a CRD representing a metric. The metric will be collected from the provider specified in the +specs.provider.name field. The query is a string in the provider-specific query language, used to obtain a metric. +Providing the metrics as CRD into a K8s cluster will facilitate the reusability of this data across multiple components. +Furthermore, this allows using multiple observability platforms for different metrics. Please note, there is a +limitation that `KeptnMetric` resource needs to be created only in `keptn-lifecycle-toolkit-system` namespace. + +A `KeptnMetric` looks like the following: + +```yaml +apiVersion: metrics.keptn.sh/v1alpha1 +kind: KeptnMetric +metadata: + name: keptnmetric-sample + namespace: keptn-lifecycle-toolkit-system +spec: + provider: + name: "" + query: "sum(kube_pod_container_resource_limits{resource='cpu'})" + fetchIntervalSeconds: 5 +``` + +Keptn metrics can be exposed as OTel metrics via port `9999` of the KLT operator. To expose them, the env +variable `EXPOSE_KEPTN_METRICS` in the operator manifest needs to be set to `true`. The default value of this variable +is `true`. To access the metrics, use the following command: + +```shell +kubectl port-forward deployment/klc-controller-manager 9999 -n keptn-lifecycle-toolkit-system +``` + +and access the metrics via your browser with: + +```http://localhost:9999/metrics``` + +#### Accessing Metrics via the Kubernetes Custom Metrics API + +`KeptnMetrics` that are located in the `keptn-lifecycle-toolkit-system` namespace can also be retrieved via the +Kubernetes Custom Metrics API. +This makes it possible to refer to these metrics via the Kubernetes *HorizontalPodAutoscaler*, as in the following +example: + +```yaml +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: podtato-head-entry + namespace: podtato-kubectl +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: podtato-head-entry + minReplicas: 1 + maxReplicas: 10 + metrics: + - type: Object + object: + metric: + name: keptnmetric-sample + describedObject: + apiVersion: metrics.keptn.sh/v1alpha1 + kind: KeptnMetric + name: keptnmetric-sample + target: + type: Value + value: "10" +``` + +You can also use the `kubectl raw` command to retrieve the values of a `KeptnMetric`, as in the following example: + +```shell +$ kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta2/namespaces/podtato-kubectl/keptnmetrics.metrics.sh/keptnmetric-sample/keptnmetric-sample" | jq . + +{ + "kind": "MetricValueList", + "apiVersion": "custom.metrics.k8s.io/v1beta2", + "metadata": {}, + "items": [ + { + "describedObject": { + "kind": "KeptnMetric", + "namespace": "keptn-lifecycle-toolkit-system", + "name": "keptnmetric-sample", + "apiVersion": "metrics.keptn.sh/v1alpha1" + }, + "metric": { + "name": "keptnmetric-sample", + "selector": { + "matchLabels": { + "app": "frontend" + } + } + }, + "timestamp": "2023-01-25T09:26:15Z", + "value": "10" + } + ] +} +``` + +You can also filter based on matching labels. So to e.g. retrieve all metrics that are labelled with `app=frontend`, you +can use the following command: + +```shell +$ kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta2/namespaces/podtato-kubectl/keptnmetrics.metrics.sh/*/*?labelSelector=app%3Dfrontend" | jq . + +{ + "kind": "MetricValueList", + "apiVersion": "custom.metrics.k8s.io/v1beta2", + "metadata": {}, + "items": [ + { + "describedObject": { + "kind": "KeptnMetric", + "namespace": "keptn-lifecycle-toolkit-system", + "name": "keptnmetric-sample", + "apiVersion": "metrics.keptn.sh/v1alpha1" + }, + "metric": { + "name": "keptnmetric-sample", + "selector": { + "matchLabels": { + "app": "frontend" + } + } + }, + "timestamp": "2023-01-25T09:26:15Z", + "value": "10" + } + ] +} +``` diff --git a/content/en/docs/concepts/overview/klc-cert-manager/_index.md b/content/en/docs/concepts/overview/klc-cert-manager/_index.md new file mode 100644 index 0000000..b76c12d --- /dev/null +++ b/content/en/docs/concepts/overview/klc-cert-manager/_index.md @@ -0,0 +1,24 @@ +--- +title: Keptn Certificate Manager +icon: concepts +layout: quickstart +weight: 5 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- + +### Keptn Cert Manager + +The Lifecycle Toolkit includes a Mutating Webhook which requires TLS certificates to be mounted as a volume in its pod. +In version 0.6.0 and later, the certificate creation +is handled automatically by +the [klt-cert-manager](https://github.com/keptn/lifecycle-toolkit/blob/main/klt-cert-manager/README.md). + +The certificate is created as a secret in the `keptn-lifecycle-toolkit-system` namespace with a renewal threshold of 12 +hours. +If it expires, the [klt-cert-manager](https://github.com/keptn/lifecycle-toolkit/blob/main/klt-cert-manager/README.md) +renews it. +The Lifecycle Toolkit operator waits for a valid certificate to be ready. +The certificate is mounted on an empty dir volume in the operator. + +When a certificate is left over from an older version, the webhook or the operator may generate errors because of an +invalid certificate. To solve this, delete the certificate and restart the operator. diff --git a/content/en/docs/crd-ref/_index.md b/content/en/docs/crd-ref/_index.md new file mode 100644 index 0000000..f4271ed --- /dev/null +++ b/content/en/docs/crd-ref/_index.md @@ -0,0 +1,15 @@ +--- +title: CRD Reference pages +description: Reference information about the KLT CRDs +weight: 100 +hidechildren: false # this flag hides all sub-pages in the sidebar-multicard.html +--- + +This section provides comprehensive reference information about the +[Custom Resource Definitions (CRDs)](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) +that are defined for the Keptn Lifecycle Toolkit. + +**NOTE: This section is under development. +Information that is published here has been reviewed for technical accuracy +but the format and content is still evolving. +We welcome your input!** diff --git a/content/en/docs/crd-ref/crd-template.md b/content/en/docs/crd-ref/crd-template.md new file mode 100644 index 0000000..d5dcec6 --- /dev/null +++ b/content/en/docs/crd-ref/crd-template.md @@ -0,0 +1,32 @@ +--- +title: +description: +weight: +hide: true +--- + +Copy this template to create a new CRD reference page. + +1. Replace the variable text in metadata with information for this page +1. Delete the `hidden: true` line +1. Delete these instructions from your file +1. Populate the page with appropriate content + +## Synopsis + +## Parameters + + + +## Usage + + + + +## Examples + +## Files + +## Differences between versions + +## See also diff --git a/content/en/docs/getting-started.md b/content/en/docs/getting-started.md new file mode 100644 index 0000000..ef7e788 --- /dev/null +++ b/content/en/docs/getting-started.md @@ -0,0 +1,197 @@ +--- +title: Getting Started +linktitle: Getting Started +description: Learn how to use the Keptn Lifecycle Toolkit. +weight: 15 +cascade: +github_subdir: "docs/content/en/docs" +path_base_for_github_subdir: "/content/en/docs-dev" +--- + +`kubectl create -f deployment.yaml` will "blindly" deploy workloads, but who needs to be notified that this deployment +is about to happen? Is your infrastructure ready? Do your downstream services meet their SLOs? Can your infrastructure +handle the deployment? + +After the deployment, beyond the standard k8s probes, how can you integrate with other tooling to automatically test the +deployment? How do you know the deployment is meeting its SLOs? Has the deployment caused any issues downstream? Who +needs to know that the deployment was successful (or unsuccessful)? + +The Keptn Lifecycle Toolkit (KLT) "wraps" a standard Kubernetes deployment and provides both workload (single service) +tests and SLO evaluations. Multiple workloads can also be logically grouped (and evaluated) as a single cohesive unit: a +Keptn Application. In other words, an application is a collection of multiple workloads. + +The Keptn Lifecycle Toolkit is a tool and vendor-neutral mechanism - it does not depend on particular GitOps tooling - +ArgoCD, Flux, Gitlab or others - KLT works with them all. + +The Keptn Lifecycle Toolkit emits signals at every stage (k8s events, OpenTelemetry metrics and traces) to ensure your +deployments are observable. + +Available steps (applicable to both workload and application entities): + +* Pre-Deployment Tasks: e.g. checking for dependant services, checking if the cluster is ready for the deployment, etc. +* Pre-Deployment Evaluations: e.g. evaluate metrics before your application gets deployed (e.g. layout of the cluster) +* Post-Deployment Tasks: e.g. trigger a test, trigger a deployment to another cluster, etc. +* Post-Deployment Evaluations: e.g. evaluate the deployment, evaluate the test results, etc. + +## What you will learn here + +* Use the Keptn Lifecycle Toolkit to control the deployment of your application +* Connect the lifecycle-toolkit to Prometheus +* Use pre-deployment tasks to check if a dependency is met before deploying a workload +* Use post-deployment tasks on an application level to send a notification + +## Prerequisites + +* A Kubernetes cluster >= Kubernetes 1.24 + * If you don't have one, we recommend [Kubernetes-in-Docker(KinD)](https://kind.sigs.k8s.io/docs/user/quick-start/) + to set up your local development environment +* kubectl installed on your system + * See () for more information + +## Check Kubernetes Version + +Run the following and ensure both client and server versions are greater than or equal to v1.24. + +```shell +kubectl version --short +``` + +The output should look like this. In this example, both client and server are at v1.24.0 so the Keptn Lifecycle Toolkit +will work. + +{{% readfile file="./snippets/tasks/k8s_version_output.md" markdown="true" %}} + +## Install the Keptn Lifecycle Toolkit + +{{% readfile file="./snippets/tasks/install.md" markdown="true" %}} + +## Check out the Getting Started Repository + +For the further progress of this guide, we need a sample application as well as some helpers which make it easier for +your to set up your environment. These things can be found in our Getting Started repository which can be checked out as +follows: + +```shell +git clone https://github.com/keptn-sandbox/lifecycle-toolkit-examples.git +cd lifecycle-toolkit-examples +``` + +## Install the required observability features + +The Keptn Lifecycle Toolkit emits OpenTelemetry data as standard but the toolkit does not come pre-bundled with +Observability backend tooling. This is deliberate as it provides flexibility for you to bring your own Observability +backend which consumes this emitted data. + +In order to use the observability features of the lifecycle toolkit, we need a monitoring and tracing backend. + +In this guide, we will use [Prometheus](https://prometheus.io/) for Metrics, [Jaeger](https://jaegertracing.io) for +Traces and [Grafana](https://github.com/grafana/) for Dashboarding. + +```shell +make install-observability +make restart-lifecycle-toolkit +``` + +## The Demo Application + +For this demonstration, we use a slightly modified version +of [the PodTatoHead](https://github.com/podtato-head/podtato-head). + + +![img.png](assets/podtatohead.png) + +Over time, we will evolve this application from a simple manifest to a Keptn-managed application. We will install it +first with kubectl and add pre- as well as post-deployment tasks. For this, we will check if the entry service is +available before the other ones get scheduled. Afterward, we will add evaluations to ensure that our infrastructure is +in a good shape before we deploy the application. Finally, we will evolve to a GitOps driven deployment and will notify +an external webhook service when the deployment has finished. + +## Install the Demo Application (Version 1) + +In the first version of the Demo application, the Keptn Lifecycle Toolkit evaluates metrics provided by prometheus and +checks if a specified amount of CPUs is available before deploying the application + +To install it, simply apply the manifest: + +```shell +make deploy-version-1 +``` + +You can watch the progress of the deployment as follows: + +### Watch workload state + +When the Lifecycle Toolkit detects workload labels ("app.kubernetes.io/name" and "keptn.sh/workload") on a resource, a +KeptnWorkloadInstance (kwi) resource will be created. Using this resource you can watch the progress of the deployment. + +```shell +kubectl get keptnworkloadinstances -n podtato-kubectl +``` + +This will show the current status of the Workloads and in which phase they are at the moment. You can get more detailed +information about the workloads by describing one of the resources: + +```shell +kubectl describe keptnworkloadinstances podtato-head-podtato-head-entry -n podtato-kubectl +``` + +Note that there are more detailed information in the event stream of the object. + +### Watch application state + +Although you didn't specify an application in your manifest, the Lifecycle Toolkit assumed that this is a single-service +application and created an ApplicationVersion (kav) resource for you. + +Using `kubectl get keptnappversions -n podtato-kubectl` you can see state of these resources. + +### Watch pods + +Obviously, you should see that the pods are starting normally. You can watch the state of the pods using: + +```shell +kubectl get pods -n podtato-kubectl +``` + +Furthermore, you can port-forward the podtato-head service to your local machine and access the application via your +browser: + +```shell +make port-forward-grafana +``` + +In your browser (, Log in with the user 'admin' and the password 'admin'), you can open the +Dashboard `Keptn Applications` and see the current state of the application which should be similar to the following: + + +![grafana.png](assets/grafana.png) + +In this screen you get the following information: + +* Successful/Failed Deployments +* Time between Deployments +* Deployment Time per Version +* The link to the Trace of the deployment + +After some time (~60 seconds), you should see one more failed deployment in your dashboard. You can click on the link to +the trace and see the reason for the failure: + + +![trace-failed.png](assets/trace-failed.png) + +In this case, we see the name of the failed pre-deployment evaluation and the reason for the failure. In this case, the +minimum amount of CPUs is not met. This is a problem we can solve by changing the treshold in the evaluation file. + +## Install the Demo Application (Version 2) + +To achieve this, we changed the operator in the evaluation file (sample-app/version-2/app-pre-deploy-eval) from `<` +to `>` and applied the new manifest: + +```shell +kubectl apply -f sample-app/version-2 +``` + +After this, you can inspect the new state of the application using the same commands as before. You should see that the +deployment is now successful and that the trace is also updated. You should also see in the Grafana Dashboards that the +deployment was successful. + +Congratulations! You successfully deployed the first application using the Keptn Lifecycle Toolkit! diff --git a/content/en/docs/tasks/implement-slack-notification/_index.md b/content/en/docs/tasks/implement-slack-notification/_index.md new file mode 100644 index 0000000..c77f37c --- /dev/null +++ b/content/en/docs/tasks/implement-slack-notification/_index.md @@ -0,0 +1,39 @@ +--- +title: Implement Slack Notification +description: Learn how to implement Slack notification as a post deployment task. +icon: concepts +layout: quickstart +weight: 24 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- + +## Create Slack Webhook + +At first, create an incoming slack webhook. +Necessary information is available in the [slack api page](https://api.slack.com/messaging/webhooks). +Once you create the webhook, you will get a URL similar to below example. + +`https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX` + +`T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX` is the secret part of the webhook which we would need in the next step. + +## Create slack-secret + +Create a `slack-secret.yaml` definition using the following command. +This will create a kubernetes secret named `slack-secret.yaml` in the `examples/sample-app/base` directory. +Before running this command change your current directory into `examples/sample-app`. + +```shell +kubectl create secret generic slack-secret --from-literal=SECURE_DATA='{"slack_hook":,"text":"Deployed PodTatoHead Application"}' -n podtato-kubectl -oyaml --dry-run=client > base/slack-secret.yaml +``` + +## Enable post deployment task + +To enable Slack notification add `post-deployment-notification` in as a postDeploymentTasks in the +[examples/sample-app/base/app.yaml](https://github.com/keptn/lifecycle-toolkit/blob/main/examples/sample-app/base/app.yaml) +file as shown below. + +```yaml + postDeploymentTasks: + - post-deployment-notification +``` diff --git a/content/en/docs/tasks/restart-application-deployment/_index.md b/content/en/docs/tasks/restart-application-deployment/_index.md new file mode 100644 index 0000000..2f005fe --- /dev/null +++ b/content/en/docs/tasks/restart-application-deployment/_index.md @@ -0,0 +1,184 @@ +--- +title: Restart an Application Deployment +description: Learn how to restart an unsuccessful Keptn Application Deployment. +icon: concepts +layout: quickstart +weight: 20 +hidechildren: true # this flag hides all sub-pages in the sidebar-multicard.html +--- + +## Restart an Application Deployment + +During the deployment of a `KeptnApp`, it might be that the deployment fails due to an unsuccessful pre-deployment +evaluation or pre-deployment task. +This could happen because of, e.g., a misconfigured target value of a `KeptnEvaluationDefinition`, or a wrong URL being +checked in a pre deployment check. + +To retry a `KeptnApp` deployment without incrementing the version of the `KeptnApp`, we introduced the concept of ** +revisions** for a `KeptnAppVersion`. This means that +whenever the spec of a `KeptnApp` changes, even though the version stays the same, the KLT Operator will create a new +revision of the `KeptnAppVersion` referring to the `KeptnApp`. + +This way, when a `KeptnApp` failed due to a misconfigured pre-deployment check, you can first fix the configuration of +the `KeptnTaskDefinition`/`KeptnEvaluationDefinition`, then +increase the value of `spec.revision` of the `KeptnApp` and finally apply the updated `KeptnApp` manifest. +This will result in a restart of the `KeptnApp`. +Afterwards, all related `KeptnWorkloadInstances` will automatically refer to the newly +created revision of the `KeptnAppVersion` to determine whether they are allowed to enter their respective deployment +phase. + +To illustrate this, let's have a look at the following example: + +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: restartable-apps + annotations: + keptn.sh/lifecycle-toolkit: "enabled" +--- +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnApp +metadata: + name: podtato-head + namespace: restartable-apps +spec: + version: "0.1.1" + revision: 1 + workloads: + - name: podtato-head-entry + version: "0.1.2" + preDeploymentTasks: + - pre-deployment-check +--- +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnTaskDefinition +metadata: + name: pre-deployment-check + namespace: restartable-apps +spec: + function: + inline: + code: | + console.error("I failed") + process.exit(1) +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: podtato-head-entry + namespace: restartable-apps + labels: + app: podtato-head +spec: + selector: + matchLabels: + component: podtato-head-entry + template: + metadata: + labels: + component: podtato-head-entry + keptn.sh/workload: podtato-head-entry + keptn.sh/app: podtato-head + keptn.sh/version: "0.1.2" + spec: + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: ghcr.io/podtato-head/entry:0.2.7 + imagePullPolicy: Always + ports: + - containerPort: 9000 + env: + - name: PODTATO_PORT + value: "9000" +``` + +In this example, the `KeptnApp` executes a pre-deployment check which clearly fails due to the `pre-deployment-check` +task, and will therefore not be able to proceed with the deployment. + +After applying this manifest, you can inspect the status of the created `KeptnAppVersion`: + +```shell +$ kubectl get keptnappversions.lifecycle.keptn.sh -n restartable-apps +NAME APPNAME VERSION PHASE +podtato-head-0.1.1-1 podtato-head 0.1.1 AppPreDeployTasks +``` + +You will notice that the `KeptnAppVersion` will stay in the `AppPreDeployTasks` phase for a while, due to the pre-check +trying to run until a certain failure threshold is reached. +Eventually, you will find the `KeptnAppVersion`'s `PredeploymentPhase` to be in a `Failed` state, with the remaining +phases being `Deprecated`. + + +```shell +$ kubectl get keptnappversions.lifecycle.keptn.sh -n restartable-apps -owide +NAME APPNAME VERSION PHASE PREDEPLOYMENTSTATUS PREDEPLOYMENTEVALUATIONSTATUS WORKLOADOVERALLSTATUS POSTDEPLOYMENTSTATUS POSTDEPLOYMENTEVALUATIONSTATUS +podtato-head-0.1.1-1 podtato-head 0.1.1 AppPreDeployTasks Failed Deprecated Deprecated Deprecated Deprecated +``` + + +Now, to fix the deployment of this application, we first need to fix the task that has failed earlier. +To do so, edit the `pre-deployment-check` `KeptnTaskDefinition` to the +following (`kubectl -n restartable-apps edit keptntaskdefinitions.lifecycle.keptn.sh pre-deployment-check`): + +```yaml +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnTaskDefinition +metadata: + name: pre-deployment-check + namespace: restartable-apps +spec: + function: + inline: + code: | + console.error("Success") +``` + +After we have done that, we can restart the deployment of our `KeptnApplication` by incrementing the `spec.revision` +field by one +(`kubectl -n restartable-apps edit keptnapps.lifecycle.keptn.sh podtato-head`): + +```yaml +apiVersion: lifecycle.keptn.sh/v1alpha2 +kind: KeptnApp +metadata: + name: podtato-head + namespace: restartable-apps +spec: + version: "0.1.1" + revision: 2 # Increased this value from 1 to 2 + workloads: + - name: podtato-head-entry + version: "0.1.2" + preDeploymentTasks: + - pre-deployment-check +``` + +After those changes have been made, you will notice a new revision of the `podtato-head` `KeptnAppVersion`: + +```shell +$ kubectl get keptnappversions.lifecycle.keptn.sh -n restartable-apps +NAME APPNAME VERSION PHASE +podtato-head-0.1.1-1 podtato-head 0.1.1 AppPreDeployTasks +podtato-head-0.1.1-2 podtato-head 0.1.1 AppDeploy +``` + +As you will see, the newly created revision `podtato-head-0.1.1-2` has made it beyond the pre-deployment check phase and +has reached its `AppDeployPhase`. + +You can also verify the execution of the `pre-deployment-check` by retrieving the list of `KeptnTasks` in +the `restartable-apps` namespace: + + +```shell +$ kubectl get keptntasks.lifecycle.keptn.sh -n restartable-apps +NAME APPNAME APPVERSION WORKLOADNAME WORKLOADVERSION JOB NAME STATUS +pre-pre-deployment-check-49827 podtato-head 0.1.1 klc-pre-pre-deployment-check--77601 Failed +pre-pre-deployment-check-65056 podtato-head 0.1.1 klc-pre-pre-deployment-check--57313 Succeeded +``` + + +You will notice that for both the `KeptnAppVersions` and `KeptnTasks` the previous failed instances are still available, +as this might be useful historical data to keep track of +what went wrong during earlier deployment attempts.