From 8494d3dc9fe69fc7488e5382c9d75e5fd4c05cf2 Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Wed, 13 Nov 2024 20:01:11 +0600 Subject: [PATCH 01/12] Add Restart Signed-off-by: Muhammad Raisul Islam Evan --- .../examples/memcached/restart/memcached.yaml | 20 ++ .../memcached/restart/opsrequest-restart.yaml | 9 + .../memcached/reconfigure-tls/_index.md | 0 .../memcached/reconfigure-tls/overview.md | 0 .../reconfigure-tls/reconfigure-tls.md | 0 docs/guides/memcached/restart/_index.md | 10 + docs/guides/memcached/restart/restart.md | 173 ++++++++++++++++++ docs/guides/memcached/tls/_index.md | 0 docs/guides/memcached/tls/overview.md | 0 docs/guides/memcached/tls/tls.md | 0 .../memcached/memcached-reconfigure-tls.png | Bin 0 -> 78410 bytes docs/images/memcached/memcached-tls.png | Bin 0 -> 45544 bytes 12 files changed, 212 insertions(+) create mode 100644 docs/examples/memcached/restart/memcached.yaml create mode 100644 docs/examples/memcached/restart/opsrequest-restart.yaml create mode 100644 docs/guides/memcached/reconfigure-tls/_index.md create mode 100644 docs/guides/memcached/reconfigure-tls/overview.md create mode 100644 docs/guides/memcached/reconfigure-tls/reconfigure-tls.md create mode 100644 docs/guides/memcached/restart/_index.md create mode 100644 docs/guides/memcached/restart/restart.md create mode 100644 docs/guides/memcached/tls/_index.md create mode 100644 docs/guides/memcached/tls/overview.md create mode 100644 docs/guides/memcached/tls/tls.md create mode 100644 docs/images/memcached/memcached-reconfigure-tls.png create mode 100644 docs/images/memcached/memcached-tls.png diff --git a/docs/examples/memcached/restart/memcached.yaml b/docs/examples/memcached/restart/memcached.yaml new file mode 100644 index 0000000000..0298f85437 --- /dev/null +++ b/docs/examples/memcached/restart/memcached.yaml @@ -0,0 +1,20 @@ +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + name: memcd-quickstart + namespace: demo +spec: + replicas: 1 + version: "1.6.22" + podTemplate: + spec: + containers: + - name: memcached + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 250m + memory: 64Mi + deletionPolicy: WipeOut diff --git a/docs/examples/memcached/restart/opsrequest-restart.yaml b/docs/examples/memcached/restart/opsrequest-restart.yaml new file mode 100644 index 0000000000..c6dd9da419 --- /dev/null +++ b/docs/examples/memcached/restart/opsrequest-restart.yaml @@ -0,0 +1,9 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: MemcachedOpsRequest +metadata: + name: memcd-new + namespace: demo +spec: + type: Restart + databaseRef: + name: memcd-quickstart \ No newline at end of file diff --git a/docs/guides/memcached/reconfigure-tls/_index.md b/docs/guides/memcached/reconfigure-tls/_index.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/guides/memcached/reconfigure-tls/overview.md b/docs/guides/memcached/reconfigure-tls/overview.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md b/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/guides/memcached/restart/_index.md b/docs/guides/memcached/restart/_index.md new file mode 100644 index 0000000000..2c6c316493 --- /dev/null +++ b/docs/guides/memcached/restart/_index.md @@ -0,0 +1,10 @@ +--- +title: Restart Memcached +menu: + docs_{{ .version }}: + identifier: restart + name: Restart + parent: mc-memcached-guides + weight: 46 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/memcached/restart/restart.md b/docs/guides/memcached/restart/restart.md new file mode 100644 index 0000000000..d5d076bac8 --- /dev/null +++ b/docs/guides/memcached/restart/restart.md @@ -0,0 +1,173 @@ +--- +title: Restart Memcached +menu: + docs_{{ .version }}: + identifier: mc-restart + name: Restart Memcached + parent: restart + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Restart Memcached + +KubeDB supports restarting the Memcached database via a MemcachedOpsRequest. Restarting is useful if some pods are got stuck in some phase, or they are not working correctly. This tutorial will show you how to use that. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Now, install KubeDB cli on your workstation and KubeDB operator in your cluster following the steps [here](/docs/setup/README.md). + +- To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. + +```bash + $ kubectl create ns demo + namespace/demo created + ``` + +> Note: YAML files used in this tutorial are stored in [docs/examples/memcached](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/memcached) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). + +## Deploy Memcached + +In this section, we are going to deploy a Memcached database using KubeDB. + +```yaml +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + name: memcd-quickstart + namespace: demo +spec: + replicas: 1 + version: "1.6.22" + podTemplate: + spec: + containers: + - name: memcached + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 250m + memory: 64Mi + deletionPolicy: WipeOut +``` + +Let's create the `Memcached` CR we have shown above, + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/restart/memcached.yaml +memcached.kubedb.com/memcd-quickstart created +``` + +## Apply Restart opsRequest + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: MemcachedOpsRequest +metadata: + name: restart + namespace: demo +spec: + type: Restart + databaseRef: + name: memcd-quickstart +``` + +- `spec.type` specifies the Type of the ops Request +- `spec.databaseRef` holds the name of the Memcached database. The database should be available in the same namespace as the opsRequest +- The meaning of `spec.timeout` & `spec.apply` fields can be found [here](/docs/guides/Memcached/concepts/opsrequest.md) + +Let's create the `MemcachedOpsRequest` CR we have shown above: + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/restart/opsrequest-restart.yaml +memcachedopsrequest.ops.kubedb.com/restart created +``` + +Now the Ops-manager operator will first restart the pods one by one. + +```shell +$ kubectl get mcops -n demo restart +NAME TYPE STATUS AGE +restart Restart Successful 3m25s + +$ kubectl get mcops -n demo restart -oyaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: MemcachedOpsRequest +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"ops.kubedb.com/v1alpha1","kind":"MemcachedOpsRequest","metadata":{"annotations":{},"name":"restart","namespace":"demo"},"spec":{"databaseRef":{"name":"memcd-quickstart"},"type":"Restart"}} + creationTimestamp: "2024-11-13T13:13:42Z" + generation: 1 + name: restart + namespace: demo + resourceVersion: "1740073" + uid: dbe5f074-f894-4c89-b34f-a4fad2322576 +spec: + apply: IfReady + databaseRef: + name: memcd-quickstart + type: Restart +status: + conditions: + - lastTransitionTime: "2024-11-13T13:13:42Z" + message: Memcached ops request is restarting the database nodes + observedGeneration: 1 + reason: Restart + status: "True" + type: Restart + - lastTransitionTime: "2024-11-13T13:13:52Z" + message: Successfully restarted pods + observedGeneration: 1 + reason: RestartPods + status: "True" + type: RestartPods + - lastTransitionTime: "2024-11-13T13:13:47Z" + message: evict pod; ConditionStatus:True; PodName:memcd-quickstart-0 + observedGeneration: 1 + status: "True" + type: EvictPod--memcd-quickstart-0 + - lastTransitionTime: "2024-11-13T13:13:47Z" + message: is pod ready; ConditionStatus:False + observedGeneration: 1 + status: "False" + type: IsPodReady + - lastTransitionTime: "2024-11-13T13:13:52Z" + message: is pod ready; ConditionStatus:True; PodName:memcd-quickstart-0 + observedGeneration: 1 + status: "True" + type: IsPodReady--memcd-quickstart-0 + - lastTransitionTime: "2024-11-13T13:13:52Z" + message: Successfully Restarted Database + observedGeneration: 1 + reason: Successful + status: "True" + type: Successful + observedGeneration: 1 + phase: Successful +``` + +## Cleaning up + +To cleanup the Kubernetes resources created by this tutorial, run: + +```bash +kubectl delete memcachedopsrequest -n demo restart +kubectl delete memcached -n demo memcd-quickstart +kubectl delete ns demo +``` + +## Next Steps + +- Monitor your Memcached database with KubeDB using [built-in Prometheus](/docs/guides/memcached/monitoring/using-builtin-prometheus.md). +- Monitor your MemcachedQL database with KubeDB using [Prometheus operator](/docs/guides/Memcached/monitoring/using-prometheus-operator.md). +- Detail concepts of [Memcached object](/docs/guides/Memcached/concepts/Memcached.md). +- Use [private Docker registry](/docs/guides/Memcached/private-registry/using-private-registry.md) to deploy MemcachedQL with KubeDB. +- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). diff --git a/docs/guides/memcached/tls/_index.md b/docs/guides/memcached/tls/_index.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/guides/memcached/tls/overview.md b/docs/guides/memcached/tls/overview.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/guides/memcached/tls/tls.md b/docs/guides/memcached/tls/tls.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/images/memcached/memcached-reconfigure-tls.png b/docs/images/memcached/memcached-reconfigure-tls.png new file mode 100644 index 0000000000000000000000000000000000000000..228acd2e8e171ccedb234eea59f6f3cd67ec114e GIT binary patch literal 78410 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�#}&18=a-QXk3#R;|ix*Yd6W9@g0 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 literal 0 HcmV?d00001 diff --git a/docs/images/memcached/memcached-tls.png b/docs/images/memcached/memcached-tls.png new file mode 100644 index 0000000000000000000000000000000000000000..2144288dd65bf81d5dfd5f745da989e666dc1247 GIT binary patch literal 45544 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 Date: Fri, 15 Nov 2024 01:50:13 +0600 Subject: [PATCH 02/12] Add TLS Overview Signed-off-by: Muhammad Raisul Islam Evan --- docs/guides/memcached/restart/restart.md | 8 +-- docs/guides/memcached/tls/_index.md | 10 ++++ docs/guides/memcached/tls/overview.md | 69 ++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 4 deletions(-) diff --git a/docs/guides/memcached/restart/restart.md b/docs/guides/memcached/restart/restart.md index d5d076bac8..9be572a343 100644 --- a/docs/guides/memcached/restart/restart.md +++ b/docs/guides/memcached/restart/restart.md @@ -166,8 +166,8 @@ kubectl delete ns demo ## Next Steps -- Monitor your Memcached database with KubeDB using [built-in Prometheus](/docs/guides/memcached/monitoring/using-builtin-prometheus.md). -- Monitor your MemcachedQL database with KubeDB using [Prometheus operator](/docs/guides/Memcached/monitoring/using-prometheus-operator.md). -- Detail concepts of [Memcached object](/docs/guides/Memcached/concepts/Memcached.md). -- Use [private Docker registry](/docs/guides/Memcached/private-registry/using-private-registry.md) to deploy MemcachedQL with KubeDB. +- Monitor your Memcached database with KubeDB using [Built-in Prometheus](/docs/guides/memcached/monitoring/using-builtin-prometheus.md). +- Monitor your Memcached database with KubeDB using [Prometheus Operator](/docs/guides/memcached/monitoring/using-prometheus-operator.md). +- Detail concepts of [Memcached](/docs/guides/memcached/concepts/memcached.md). +- Use [private Docker registry](/docs/guides/memcached/private-registry/using-private-registry.md) to deploy Memcached with KubeDB. - Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). diff --git a/docs/guides/memcached/tls/_index.md b/docs/guides/memcached/tls/_index.md index e69de29bb2..83882bc4aa 100644 --- a/docs/guides/memcached/tls/_index.md +++ b/docs/guides/memcached/tls/_index.md @@ -0,0 +1,10 @@ +--- +title: Run Memcached with TLS +menu: + docs_{{ .version }}: + identifier: mc-tls + name: TLS/SSL Encryption + parent: mc-memcached-guides + weight: 45 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/memcached/tls/overview.md b/docs/guides/memcached/tls/overview.md index e69de29bb2..485402db16 100644 --- a/docs/guides/memcached/tls/overview.md +++ b/docs/guides/memcached/tls/overview.md @@ -0,0 +1,69 @@ +--- +title: Memcached TLS/SSL Encryption Overview +menu: + docs_{{ .version }}: + identifier: mc-tls-overview + name: Overview + parent: mc-tls + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Memcached TLS/SSL Encryption + +**Prerequisite :** To configure TLS/SSL in `Memcached`, `KubeDB` uses `cert-manager` to issue certificates. So first you have to make sure that the cluster has `cert-manager` installed. To install `cert-manager` in your cluster following steps [here](https://cert-manager.io/docs/installation/kubernetes/). + +To issue a certificate, the following crd of `cert-manager` is used: + +- `Issuer/ClusterIssuer`: Issuers, and ClusterIssuers represent certificate authorities (CAs) that are able to generate signed certificates by honoring certificate signing requests. All cert-manager certificates require a referenced issuer that is in a ready condition to attempt to honor the request. You can learn more details [here](https://cert-manager.io/docs/concepts/issuer/). + +- `Certificate`: `cert-manager` has the concept of Certificates that define a desired x509 certificate which will be renewed and kept up to date. You can learn more details [here](https://cert-manager.io/docs/concepts/certificate/). + +**Memcached CRD Specification :** + +KubeDB uses following crd fields to enable SSL/TLS encryption in `Memcached`. + +- `spec:` + - `tls:` + - `issuerRef` + - `certificates` + +Read about the fields in details from [Memcached concept](/docs/guides/memcached/concepts/memcached.md), + +`KubeDB` uses the `issuer` or `clusterIssuer` referenced in the `tls.issuerRef` field, and the certificate specs provided in `tls.certificate` to generate certificate secrets using `Issuer/ClusterIssuers` specification. These certificates secrets including `ca.crt`, `tls.crt` and `tls.key` etc. are used to configure `Memcached` server, exporter etc. respectively. + +## How TLS/SSL configures in Memcached + +The following figure shows how `KubeDB` enterprise used to configure TLS/SSL in Memcached. Open the image in a new tab to see the enlarged version. + +
+Deploy Memcached with TLS/SSL +
Fig: Deploy Memcached with TLS/SSL
+
+ +Deploying Memcached with TLS/SSL configuration process consists of the following steps: + +1. At first, a user creates a `Issuer/ClusterIssuer` cr. + +2. Then the user creates a `Memcached` cr which refers to the `Issuer/ClusterIssuer` cr that the user created in the previous step. + +3. `KubeDB` Provisioner operator watches for the `Memcached` cr. + +4. When it finds one, it creates `Secret`, `Service`, etc. for the `Memcached` database. + +5. `KubeDB` Ops-manager operator watches for `Memcached`(5c), `Issuer/ClusterIssuer`(5b), `Secret` and `Service`(5a). + +6. When it finds all the resources(`Memcached`, `Issuer/ClusterIssuer`, `Secret`, `Service`), it creates `Certificates` by using `tls.issuerRef` and `tls.certificates` field specification from `Memcached` cr. + +7. `cert-manager` watches for certificates. + +8. When it finds one, it creates certificate secrets `tls-secrets`(server, client, exporter secrets etc.) that holds the actual certificate signed by the CA. + +9. `KubeDB` Provisioner operator watches for the Certificate secrets `tls-secrets`. + +10. When it finds all the tls-secret, it creates the related `PetSets` so that Memcached database can be configured with TLS/SSL. + +In the next doc, we are going to show a step-by-step guide on how to configure a `Memcached` database with TLS/SSL. \ No newline at end of file From 948352fc1e3fc5a111c54864ec1c1a9c03fcf471 Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Fri, 15 Nov 2024 18:02:06 +0600 Subject: [PATCH 03/12] Add TLS and Reconfigure TLS Signed-off-by: Muhammad Raisul Islam Evan --- .../memcached/reconfigure-tls/_index.md | 10 + .../memcached/reconfigure-tls/overview.md | 51 ++ .../reconfigure-tls/reconfigure-tls.md | 539 ++++++++++++++++++ docs/guides/memcached/restart/restart.md | 4 +- docs/guides/memcached/tls/tls.md | 229 ++++++++ 5 files changed, 831 insertions(+), 2 deletions(-) diff --git a/docs/guides/memcached/reconfigure-tls/_index.md b/docs/guides/memcached/reconfigure-tls/_index.md index e69de29bb2..a06a6b45a7 100644 --- a/docs/guides/memcached/reconfigure-tls/_index.md +++ b/docs/guides/memcached/reconfigure-tls/_index.md @@ -0,0 +1,10 @@ +--- +title: Reconfigure Memcached TLS/SSL +menu: + docs_{{ .version }}: + identifier: mc-reconfigure-tls + name: Reconfigure TLS/SSL + parent: mc-memcached-guides + weight: 46 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/memcached/reconfigure-tls/overview.md b/docs/guides/memcached/reconfigure-tls/overview.md index e69de29bb2..07f961b238 100644 --- a/docs/guides/memcached/reconfigure-tls/overview.md +++ b/docs/guides/memcached/reconfigure-tls/overview.md @@ -0,0 +1,51 @@ +--- +title: Reconfiguring TLS of Memcached +menu: + docs_{{ .version }}: + identifier: mc-reconfigure-tls-overview + name: Overview + parent: mc-reconfigure-tls + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Reconfiguring TLS of Memcached Database + +This guide will give an overview on how KubeDB Ops-manager operator reconfigures TLS configuration i.e. add TLS, remove TLS, update issuer/cluster issuer or Certificates and rotate the certificates of a `Memcached` database. + +## Before You Begin +- You should be familiar with the following `KubeDB` concepts: + - [Memcached](/docs/guides/memcached/concepts/memcached.md) + - [MemcachedOpsRequest](/docs/guides/memcached/concepts/memcached-opsrequest.md) + +## How Reconfiguring Memcached TLS Configuration Process Works + +The following diagram shows how KubeDB Ops-manager operator reconfigures TLS of a `Memcached` database. Open the image in a new tab to see the enlarged version. + +
+  Reconfiguring TLS process of Memcached +
Fig: Reconfiguring TLS process of Memcached
+
+ +The Reconfiguring Memcached TLS process consists of the following steps: + +1. At first, a user creates a `Memcached` Custom Resource (CR). + +2. `KubeDB` Community operator watches the `Memcached` CR. + +3. When the operator finds a `Memcached` CR, it creates required number of `PetSets` and related necessary stuff like appbinding, services, etc. + +4. Then, in order to reconfigure the TLS configuration of the `Memcached` database the user creates a `MemcachedOpsRequest` CR with the desired version. + +5. `KubeDB` Enterprise operator watches the `MemcachedOpsRequest` CR. + +6. When it finds a `MemcachedOpsRequest` CR, it halts the `Memcached` object which is referred from the `MemcachedOpsRequest`. So, the `KubeDB` Community operator doesn't perform any operations on the `Memcached` object during the reconfiguring process. + +7. By looking at the target version from `MemcachedOpsRequest` CR, `KubeDB` Enterprise operator will add, remove, update or rotate TLS configuration based on the Ops Request yaml. + +8. After successfully reconfiguring `Memcached` object, the `KubeDB` Enterprise operator resumes the `Memcached` object so that the `KubeDB` Community operator can resume its usual operations. + +In the next doc, we are going to show a step-by-step guide on updating of a Memcached database using update operation. \ No newline at end of file diff --git a/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md b/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md index e69de29bb2..4c783ea6cb 100644 --- a/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md @@ -0,0 +1,539 @@ +--- +title: Reconfigure Memcached TLS/SSL Encryption +menu: + docs_{{ .version }}: + identifier: mc-reconfigure-tls-standalone + name: Memcahced Reconfigure TLS + parent: mc-reconfigure-tls + weight: 20 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Reconfigure Memcached TLS/SSL (Transport Encryption) + +KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL certificates for existing Memcached database via a MemcachedOpsRequest. This tutorial will show you how to use KubeDB to reconfigure TLS/SSL encryption. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Install [`cert-manger`](https://cert-manager.io/docs/installation/) v1.0.0 or later to your cluster to manage your SSL/TLS certificates. + +- Now, install KubeDB cli on your workstation and KubeDB operator in your cluster following the steps [here](/docs/setup/README.md). + +- To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. + + ```bash + $ kubectl create ns demo + namespace/demo created + ``` + +> Note: YAML files used in this tutorial are stored in [docs/examples/memcached](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/memcached) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). + +## Add TLS to a Memcached database + +In this tutorial, we are going to reconfigure TLS of Memcached. +Here, We are going to create a Memcached database without TLS and then reconfigure the database to use TLS. + +### Deploy Memcached without TLS + +In this section, we are going to deploy a Memcached database without TLS. In the next few sections we will add reconfigure TLS using `MemcachedOpsRequest` CRD. Below is the YAML of the `Memcached` CR that we are going to create, + +```yaml +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + name: memcd-quickstart + namespace: demo +spec: + replicas: 1 + version: "1.6.22" + deletionPolicy: WipeOut +``` + +Let's create the `Memcached` CR we have shown above, + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/reconfigure-tls/memcached.yaml +memcached.kubedb.com/memcd-quickstart created +``` + +Now, wait until `memcd-quickstart` has status `Ready`. i.e, + +```bash +$ watch kubectl get mc -n demo +Every 2.0s: kubectl get mc -n demo +NAME VERSION STATUS AGE +memcd-quickstart 1.6.22 Ready 26s +``` + +Now, we can connect to this database through memcached-cli verify that the TLS is disabled. + +```bash +$ kc port-forward -n demo memcd-quickstart-0 11211 +Forwarding from 127.0.0.1:11211 -> 11211 +Forwarding from [::1]:11211 -> 11211 +Handling connection for 11211 + +$ telnet 127.0.0.1 11211 +Trying 127.0.0.1... +Connected to 127.0.0.1. +Escape character is '^]'. + +# Authentication +set key 0 0 21 +user ukwcbtebbrwastqg +STORED + +# Set/Write a value +set mc-key 0 9999 8 +mc-value +STORED + +# Get/Read a value +get mc-key +VALUE mc-key 0 8 +mc-value +END + +# Current Stats Settings +stats settings +... +ssl_enabled no +ssl_chain_cert (null) +ssl_key (null) +ssl_ca_cert NULL +... +END + +quit +``` + +We can verify from the above output that TLS is disabled for this database. + +### Create Issuer/ StandaloneIssuer + +Now, We are going to create an example `Issuer` that will be used to enable SSL/TLS in Memcached. Alternatively, you can follow this [cert-manager tutorial](https://cert-manager.io/docs/configuration/ca/) to create your own `Issuer`. + +- Start off by generating a ca certificates using openssl. + +```bash +$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=memcached/O=kubedb" +Generating a RSA private key +................+++++ +........................+++++ +writing new private key to './ca.key' +----- +``` + +- Now, we are going to create a ca-secret using the certificate files that we have just generated. + +```bash +$ kubectl create secret tls memcached-ca \ + --cert=ca.crt \ + --key=ca.key \ + --namespace=demo +secret/memcached-ca created +``` + +Now, Let's create an `Issuer` using the `memcached-ca` secret that we have just created. The `YAML` file looks like this: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: memcached-ca-issuer + namespace: demo +spec: + ca: + secretName: memcached-ca +``` + +Let's apply the `YAML` file: + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/reconfigure-tls/issuer.yaml +issuer.cert-manager.io/memcached-ca-issuer created +``` + +### Create MemcachedOpsRequest + +In order to add TLS to the database, we have to create a `MemcachedOpsRequest` CRO with our created issuer. Below is the YAML of the `MemcachedOpsRequest` CRO that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: MemcachedOpsRequest +metadata: + name: mc-add-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: memcd-quickstart + tls: + issuerRef: + name: memcached-ca-issuer + kind: Issuer + apiGroup: "cert-manager.io" + certificates: + - alias: client + subject: + organizations: + - memcached + organizationalUnits: + - client +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing reconfigure TLS operation on `memcd-quickstart` database. +- `spec.type` specifies that we are performing `ReconfigureTLS` on our database. +- `spec.tls.issuerRef` specifies the issuer name, kind and API group. +- `spec.tls.certificates` specifies the certificates. You can learn more about this field from [here](/docs/guides/memcached/concepts/memcached.md#spectls). + +Let's create the `MemcachedOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/reconfigure-tls/mc-add-tls.yaml +Memcachedopsrequest.ops.kubedb.com/rd-add-tls created +``` + +#### Verify TLS Enabled Successfully + +Let's wait for `MemcachedOpsRequest` to be `Successful`. Run the following command to watch `MemcachedOpsRequest` CRO, + +```bash +$ kubectl get Memcachedopsrequest -n demo +Every 2.0s: kubectl get Memcachedopsrequest -n demo +NAME TYPE STATUS AGE +mc-add-tls ReconfigureTLS Successful 79s +``` + +We can see from the above output that the `MemcachedOpsRequest` has succeeded. + +Now, connect to this database by exec into a pod and verify if `tls` has been set up as intended. + +```bash +$ kubectl describe secret -n demo memcd-quickstart-client-cert +Name: memcd-quickstart-client-cert +Namespace: demo +Labels: app.kubernetes.io/component=database + app.kubernetes.io/instance=memcd-quickstart + app.kubernetes.io/managed-by=kubedb.com + app.kubernetes.io/name=memcacheds.kubedb.com + controller.cert-manager.io/fao=true +Annotations: cert-manager.io/alt-names: + cert-manager.io/certificate-name: memcd-quickstart-client-cert + cert-manager.io/common-name: memcached + cert-manager.io/ip-sans: + cert-manager.io/issuer-group: cert-manager.io + cert-manager.io/issuer-kind: Issuer + cert-manager.io/issuer-name: memcached-ca-issuer + cert-manager.io/subject-organizationalunits: client + cert-manager.io/subject-organizations: memcached + cert-manager.io/uri-sans: + +Type: kubernetes.io/tls + +Data +==== +ca.crt: 1159 bytes +tls-combined.pem: 2868 bytes +tls.crt: 1188 bytes +tls.key: 1679 bytes +``` + +Now, we can connect using tls-certs to connect to the Memcached and write some data + +```bash +```bash +$ kc port-forward -n demo memcd-quickstart-0 11211 +Forwarding from 127.0.0.1:11211 -> 11211 +Forwarding from [::1]:11211 -> 11211 +Handling connection for 11211 + +$ telnet 127.0.0.1 11211 +Trying 127.0.0.1... +Connected to 127.0.0.1. +Escape character is '^]'. + +# Authentication +set key 0 0 21 +user ukwcbtebbrwastqg +STORED + +# Set/Write a value +set mc-key 0 9999 8 +mc-value +STORED + +# Get/Read a value +get mc-key +VALUE mc-key 0 8 +mc-value +END + +# Current Stats Settings +stats settings +... +ssl_enabled yes +ssl_chain_cert /usr/certs/server.crt +ssl_key /usr/certs/server.key +ssl_ca_cert /usr/certs/ca.crt +... +END + +quit +``` + +## Rotate Certificate + +Now, we are going to rotate the certificate of this database. + +### Create MemcachedOpsRequest + +Now we are going to rotate certificates using a MemcachedOpsRequest. Below is the yaml of the ops request that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: MemcachedOpsRequest +metadata: + name: myops-rotate + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: memcd-quickstart + tls: + rotateCertificates: true +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing reconfigure TLS operation on `memcd-quickstart` database. +- `spec.type` specifies that we are performing `ReconfigureTLS` on our database. +- `spec.tls.rotateCertificates` specifies that we want to rotate the certificate of this database. + +Let's create the `MemcachedOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/reconfigure-tls/mc-ops-rotate.yaml +memcachedopsrequest.ops.kubedb.com/mc-ops-rotate created +``` + +#### Verify Certificate Rotated Successfully + +Let's wait for `MemcachedOpsRequest` to be `Successful`. Run the following command to watch `MemcachedOpsRequest` CRO, + +```bash +$ watch kubectl get memcachedopsrequest -n demo +Every 2.0s: kubectl get memcachedopsrequest -n demo +NAME TYPE STATUS AGE +mc-ops-rotate ReconfigureTLS Successful 5m5s +``` + +We can see from the above output that the `MemcachedOpsRequest` has succeeded. + +## Change Issuer/ClusterIssuer + +Now, we are going to change the issuer of this database. + +- Let's create a new ca certificate and key using a different subject `CN=memcached-update,O=kubedb-updated`. + +```bash +$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=memcached-updated/O=kubedb-updated" +Generating a RSA private key +..............................................................+++++ +......................................................................................+++++ +writing new private key to './ca.key' +----- +``` + +- Now we are going to create a new ca-secret using the certificate files that we have just generated. + +```bash +$ kubectl create secret tls memcached-new-ca \ + --cert=ca.crt \ + --key=ca.key \ + --namespace=demo +secret/memcached-new-ca created +``` + +Now, Let's create a new `Issuer` using the `memcached-new-ca` secret that we have just created. The `YAML` file looks like this: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: mc-new-issuer + namespace: demo +spec: + ca: + secretName: memcached-new-ca +``` + +Let's apply the `YAML` file: + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/reconfigure-tls/new-issuer.yaml +issuer.cert-manager.io/mc-new-issuer created +``` + +### Create MemcachedOpsRequest + +In order to use the new issuer to issue new certificates, we have to create a `MemcachedOpsRequest` CRO with the newly created issuer. Below is the YAML of the `MemcachedOpsRequest` CRO that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: MemcachedOpsRequest +metadata: + name: mc-change-issuer + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: memcd-quickstart + tls: + issuerRef: + name: mc-new-issuer + kind: Issuer + apiGroup: "cert-manager.io" +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing reconfigure TLS operation on `memcd-quickstart` database. +- `spec.type` specifies that we are performing `ReconfigureTLS` on our database. +- `spec.tls.issuerRef` specifies the issuer name, kind and api group. + +Let's create the `MemcachedOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/reconfigure-tls/mc-change-issuer.yaml +Memcachedopsrequest.ops.kubedb.com/mc-change-issuer created +``` + +#### Verify Issuer is changed successfully + +Let's wait for `MemcachedOpsRequest` to be `Successful`. Run the following command to watch `MemcachedOpsRequest` CRO, + +```bash +$ kubectl get memcachedopsrequest -n demo +Every 2.0s: kubectl get memcachedopsrequest -n demo +NAME TYPE STATUS AGE +mc-change-issuer ReconfigureTLS Successful 4m65s +``` + +We can see from the above output that the `MemcachedOpsRequest` has succeeded. + +## Remove TLS from the Database + +Now, we are going to remove TLS from this database using a MemcachedOpsRequest. + +### Create MemcachedOpsRequest + +Below is the YAML of the `MemcachedOpsRequest` CRO that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: MemcachedOpsRequest +metadata: + name: mc-ops-remove + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: memcd-quickstart + tls: + remove: true +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing reconfigure TLS operation on `memcd-quickstart` database. +- `spec.type` specifies that we are performing `ReconfigureTLS` on our database. +- `spec.tls.remove` specifies that we want to remove tls from this database. + +Let's create the `MemcachedOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/reconfigure-tls/mc-ops-remove.yaml +Memcachedopsrequest.ops.kubedb.com/mc-ops-remove created +``` + +#### Verify TLS Removed Successfully + +Let's wait for `MemcachedOpsRequest` to be `Successful`. Run the following command to watch `MemcachedOpsRequest` CRO, + +```bash +$ kubectl get memcachedopsrequest -n demo +Every 2.0s: kubectl get memcachedopsrequest -n demo +NAME TYPE STATUS AGE +mc-ops-remove ReconfigureTLS Successful 105s +``` + +We can see from the above output that the `MemcachedOpsRequest` has succeeded. + +Now, Lets check Memcached TLS is disabled or not. + +```bash +$ kc port-forward -n demo memcd-quickstart-0 11211 +Forwarding from 127.0.0.1:11211 -> 11211 +Forwarding from [::1]:11211 -> 11211 +Handling connection for 11211 + +$ telnet 127.0.0.1 11211 +Trying 127.0.0.1... +Connected to 127.0.0.1. +Escape character is '^]'. + +# Authentication +set key 0 0 21 +user ukwcbtebbrwastqg +STORED + +# Current Stats Settings +stats settings +... +ssl_enabled no +ssl_chain_cert (null) +ssl_key (null) +ssl_ca_cert NULL +... +END + +quit +``` + +So, we can see from the above that, output that tls is disabled successfully. + +## Cleaning up + +To clean up the Kubernetes resources created by this tutorial, run: + +```bash +$ kubectl patch -n demo memcached/memcd-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +memcached.kubedb.com/memcd-quickstart patched + +$ kubectl delete memcached -n demo memcd-quickstart +memcached.kubedb.com/memcd-quickstart deleted + +$ kubectl delete issuer -n demo memcached-ca-issuer mc-new-issuer +issuer.cert-manager.io "memcached-ca-issuer" deleted +issuer.cert-manager.io "mc-new-issuer" deleted + +$ kubectl delete memcachedopsrequest -n demo mc-add-tls mc-ops-remove mc-ops-rotate mc-change-issuer +memcachedopsrequest.ops.kubedb.com "mc-add-tls" deleted +memcachedopsrequest.ops.kubedb.com "mc-ops-remove" deleted +memcachedopsrequest.ops.kubedb.com "mc-ops-rotate" deleted +memcachedopsrequest.ops.kubedb.com "mc-change-issuer" deleted +``` + +## Next Steps + +- Detail concepts of [Memcached](/docs/guides/memcached/concepts/memcached.md). +- Monitor your Memcached database with KubeDB using [out-of-the-box Prometheus operator](/docs/guides/memcached/monitoring/using-prometheus-operator.md). +- Monitor your Memcached database with KubeDB using [out-of-the-box builtin-Prometheus](/docs/guides/memcached/monitoring/using-builtin-prometheus.md). diff --git a/docs/guides/memcached/restart/restart.md b/docs/guides/memcached/restart/restart.md index 9be572a343..3aefe44ba2 100644 --- a/docs/guides/memcached/restart/restart.md +++ b/docs/guides/memcached/restart/restart.md @@ -3,8 +3,8 @@ title: Restart Memcached menu: docs_{{ .version }}: identifier: mc-restart - name: Restart Memcached - parent: restart + name: Restart + parent: TLS/SSL Encryption weight: 10 menu_name: docs_{{ .version }} section_menu_id: guides diff --git a/docs/guides/memcached/tls/tls.md b/docs/guides/memcached/tls/tls.md index e69de29bb2..7c9f5de31a 100644 --- a/docs/guides/memcached/tls/tls.md +++ b/docs/guides/memcached/tls/tls.md @@ -0,0 +1,229 @@ +--- +title: Memcached TLS/SSL Encryption +menu: + docs_{{ .version }}: + identifier: mc-tls + name: TLS + parent: mc-tls + weight: 20 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Run Memcached with TLS/SSL (Transport Encryption) + +KubeDB supports providing TLS/SSL encryption for Memcached. This tutorial will show you how to use KubeDB to run a Memcached database with TLS/SSL encryption. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Install [`cert-manger`](https://cert-manager.io/docs/installation/) v1.0.0 or later to your cluster to manage your SSL/TLS certificates. + +- Now, install KubeDB cli on your workstation and KubeDB operator in your cluster following the steps [here](/docs/setup/README.md). + +- To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. + + ```bash + $ kubectl create ns demo + namespace/demo created + ``` + +> Note: YAML files used in this tutorial are stored in [docs/examples/Memcached](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/Memcached) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). + +## Overview + +KubeDB uses following crd fields to enable SSL/TLS encryption in Memcached. + +- `spec:` + - `tls:` + - `issuerRef` + - `certificate` + +Read about the fields in details in [Memcached concept](/docs/guides/memcached/concepts/memcached.md), + +## Create Issuer/ ClusterIssuer + +We are going to create an example `Issuer` that will be used throughout the duration of this tutorial to enable SSL/TLS in Memcached. Alternatively, you can follow this [cert-manager tutorial](https://cert-manager.io/docs/configuration/ca/) to create your own `Issuer`. + +- Start off by generating you ca certificates using openssl. + +```bash +$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=Memcached/O=kubedb" +``` + +- Now create a ca-secret using the certificate files you have just generated. + +```bash +$ kubectl create secret tls memcached-ca \ + --cert=ca.crt \ + --key=ca.key \ + --namespace=demo +``` + +Now, create an `Issuer` using the `ca-secret` you have just created. The `YAML` file looks like this: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: memcached-ca-issuer + namespace: demo +spec: + ca: + secretName: memcached-ca +``` + +Apply the `YAML` file: + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/tls/issuer.yaml +issuer.cert-manager.io/memcached-ca-issuer created +``` + +## TLS/SSL encryption in Memcached Standalone + +Below is the YAML for Memcached Standalone. + +```yaml +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + name: memcd-quickstart + namespace: demo +spec: + replicas: 1 + version: "1.6.22" + tls: + issuerRef: + apiGroup: "cert-manager.io" + kind: Issuer + name: memcached-ca-issuer + certificates: + - alias: client + ipAddresses: + - 127.0.0.1 + - 192.168.0.252 + deletionPolicy: WipeOut +``` + +### Deploy Memcached + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/tls/mc-tls.yaml +memcached.kubedb.com/memcd-quickstart created +``` + +Now, wait until `memcd-quickstart` has status `Ready`. i.e, + +```bash +$ watch kubectl get rd -n demo +Every 2.0s: kubectl get memcached -n demo +NAME VERSION STATUS AGE +memcd-quickstart 1.6.22 Ready 19m +``` + +### Verify TLS/SSL in Memcached + +Now, connect to this database by exec into a pod and verify if `tls` has been set up as intended. + +```bash +$ kubectl describe secret -n demo memcd-quickstart-client-cert +Name: memcd-quickstart-client-cert +Namespace: demo +Labels: app.kubernetes.io/component=database + app.kubernetes.io/instance=memcd-quickstart + app.kubernetes.io/managed-by=kubedb.com + app.kubernetes.io/name=memcacheds.kubedb.com + controller.cert-manager.io/fao=true +Annotations: cert-manager.io/alt-names: + cert-manager.io/certificate-name: memcd-quickstart-client-cert + cert-manager.io/common-name: memcached + cert-manager.io/ip-sans: 127.0.0.1,192.168.0.252 + cert-manager.io/issuer-group: cert-manager.io + cert-manager.io/issuer-kind: Issuer + cert-manager.io/issuer-name: memcached-ca-issuer + cert-manager.io/uri-sans: + +Type: kubernetes.io/tls + +Data +==== +tls.crt: 1168 bytes +tls.key: 1675 bytes +ca.crt: 1159 bytes +tls-combined.pem: 2844 bytes +``` + +Now, we can connect to the Memcached and read/write some data + +```bash +$ kubectl port-forward -n demo memcd-quickstart-0 11211 +orwarding from 127.0.0.1:11211 -> 11211 +Forwarding from [::1]:11211 -> 11211 +``` + +Telnet doesn't support TLS. To overcome this, we will use socat: +```bash +$ socat -d -d \ + TCP-LISTEN:12345,reuseaddr,fork \ + OPENSSL:localhost:11211,cert=/path/client.crt,key=/path/client.key,cafile=/path/ca.crt,verify=1 +2024/11/15 12:02:41 socat[46145] N listening on AF=10 [0000:0000:0000:0000:0000:0000:0000:0000]:12345 +``` +Now connect to the memcached via socat using telnet: +```bash +$ telnet 127.0.0.1 12345 +Trying 127.0.0.1... +Connected to 127.0.0.1. +Escape character is '^]'. + +# Set username and password for authentication. +set key 0 0 21 +user **znjl**ketkdj** +STORED + +# Set/Write a value +set mc-key 0 9999 8 +mc-value +STORED + +# Get/Read a value +get mc-key +VALUE mc-key 0 8 +mc-value +END + +# Current Stats Settings +stats settings +... +ssl_enabled yes +ssl_chain_cert /usr/certs/server.crt +ssl_key /usr/certs/server.key +ssl_ca_cert /usr/certs/ca.crt +... +END + +quit +``` +## Cleaning up + +To clean up the Kubernetes resources created by this tutorial, run: + +```bash +$ kubectl patch -n demo memcached/memcd-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +memcached.kubedb.com/memcd-quickstart patched + +$ kubectl delete -n demo memcached memcd-quickstart +memcached.kubedb.com "memcd-quickstart" deleted + +$ kubectl delete issuer -n demo memcached-ca-issuer +issuer.cert-manager.io "memcached-ca-issuer" deleted +``` + +## Next Steps + +- Detail concepts of [Memcached object](/docs/guides/memcached/concepts/memcached.md). +- Monitor your Memcached database with KubeDB using [out-of-the-box Prometheus operator](/docs/guides/memcached/monitoring/using-prometheus-operator.md). +- Monitor your Memcached database with KubeDB using [out-of-the-box builtin-Prometheus](/docs/guides/memcached/monitoring/using-builtin-prometheus.md). From 46ce45d622e1767b6f2ff25ac9a8ecdea7e2c7da Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Fri, 15 Nov 2024 18:23:08 +0600 Subject: [PATCH 04/12] Fix-URL Signed-off-by: Muhammad Raisul Islam Evan --- docs/guides/memcached/restart/restart.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/memcached/restart/restart.md b/docs/guides/memcached/restart/restart.md index 3aefe44ba2..85ea8c3f04 100644 --- a/docs/guides/memcached/restart/restart.md +++ b/docs/guides/memcached/restart/restart.md @@ -81,7 +81,7 @@ spec: - `spec.type` specifies the Type of the ops Request - `spec.databaseRef` holds the name of the Memcached database. The database should be available in the same namespace as the opsRequest -- The meaning of `spec.timeout` & `spec.apply` fields can be found [here](/docs/guides/Memcached/concepts/opsrequest.md) +- The meaning of `spec.timeout` & `spec.apply` fields can be found [here](/docs/guides/memcached/concepts/memcached-opsrequest.md) Let's create the `MemcachedOpsRequest` CR we have shown above: From 72dd1bd835886767e8132dee404cf2ffed577684 Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Mon, 18 Nov 2024 18:07:30 +0600 Subject: [PATCH 05/12] Add reconfigureTLS missing part Signed-off-by: Muhammad Raisul Islam Evan --- .../reconfigure-tls/reconfigure-tls.md | 404 +++++++++++++++++- 1 file changed, 396 insertions(+), 8 deletions(-) diff --git a/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md b/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md index 4c783ea6cb..001eada0e5 100644 --- a/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md @@ -212,9 +212,101 @@ NAME TYPE STATUS AGE mc-add-tls ReconfigureTLS Successful 79s ``` -We can see from the above output that the `MemcachedOpsRequest` has succeeded. +We can see from the above output that the `MemcachedOpsRequest` has succeeded. If we describe the `MemcachedOpsRequest` we will get an overview of the steps that were followed. -Now, connect to this database by exec into a pod and verify if `tls` has been set up as intended. +```bash +$ kubectl describe mcops -n demo mc-add-tls +Name: mc-add-tls +Namespace: demo +Labels: +Annotations: +API Version: ops.kubedb.com/v1alpha1 +Kind: MemcachedOpsRequest +Metadata: + Creation Timestamp: 2024-11-15T11:10:37Z + Generation: 1 + Resource Version: 1782138 + UID: 25123c6c-90e1-4a11-a060-42a1f75bc15d +Spec: + Apply: IfReady + Database Ref: + Name: memcd-quickstart + Tls: + Certificates: + Alias: client + Subject: + Organizational Units: + client + Organizations: + memcached + Issuer Ref: + API Group: cert-manager.io + Kind: Issuer + Name: memcached-ca-issuer + Type: ReconfigureTLS +Status: + Conditions: + Last Transition Time: 2024-11-15T11:10:37Z + Message: Memcached ops request is reconfiguring TLS + Observed Generation: 1 + Reason: ReconfigureTLS + Status: True + Type: ReconfigureTLS + Last Transition Time: 2024-11-15T11:10:50Z + Message: Successfully synced all certificates + Observed Generation: 1 + Reason: CertificateSynced + Status: True + Type: CertificateSynced + Last Transition Time: 2024-11-15T11:10:45Z + Message: get certificate; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: GetCertificate + Last Transition Time: 2024-11-15T11:10:45Z + Message: check ready condition; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: CheckReadyCondition + Last Transition Time: 2024-11-15T11:10:45Z + Message: check issuing condition; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: CheckIssuingCondition + Last Transition Time: 2024-11-15T11:11:10Z + Message: Successfully restarted pods + Observed Generation: 1 + Reason: RestartPods + Status: True + Type: RestartPods + Last Transition Time: 2024-11-15T11:10:55Z + Message: evict pod; ConditionStatus:True; PodName:memcd-quickstart-0 + Observed Generation: 1 + Status: True + Type: EvictPod--memcd-quickstart-0 + Last Transition Time: 2024-11-15T11:10:55Z + Message: is pod ready; ConditionStatus:False + Observed Generation: 1 + Status: False + Type: IsPodReady + Last Transition Time: 2024-11-15T11:11:00Z + Message: is pod ready; ConditionStatus:True; PodName:memcd-quickstart-0 + Observed Generation: 1 + Status: True + Type: IsPodReady--memcd-quickstart-0 + Last Transition Time: 2024-11-15T11:11:00Z + Message: Successfully reconfigured TLS + Observed Generation: 1 + Reason: Successful + Status: True + Type: Successful + Observed Generation: 1 + Phase: Successful +Events: + +``` + +Now, let's describe the client.crt of running Memcached database. ```bash $ kubectl describe secret -n demo memcd-quickstart-client-cert @@ -248,7 +340,6 @@ tls.key: 1679 bytes Now, we can connect using tls-certs to connect to the Memcached and write some data -```bash ```bash $ kc port-forward -n demo memcd-quickstart-0 11211 Forwarding from 127.0.0.1:11211 -> 11211 @@ -291,7 +382,16 @@ quit ## Rotate Certificate -Now, we are going to rotate the certificate of this database. +Now, we are going to rotate the certificate of this database. First let’s check the current expiration date of the certificate: +```bash +$ kubectl port-forward -n demo memcd-quickstart-0 11211 +Forwarding from 127.0.0.1:11211 -> 11211 +Forwarding from [::1]:11211 -> 11211 + +$ openssl x509 -in <(openssl s_client -connect 127.0.0.1:11211 -showcerts < /dev/null 2>/dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p') -noout -enddate +notAfter=Feb 16 04:58:37 2025 GMT +``` +So, the certificate will expire on this time Feb 16 04:58:37 2025 GMT. ### Create MemcachedOpsRequest @@ -312,7 +412,6 @@ spec: ``` Here, - - `spec.databaseRef.name` specifies that we are performing reconfigure TLS operation on `memcd-quickstart` database. - `spec.type` specifies that we are performing `ReconfigureTLS` on our database. - `spec.tls.rotateCertificates` specifies that we want to rotate the certificate of this database. @@ -335,7 +434,106 @@ NAME TYPE STATUS AGE mc-ops-rotate ReconfigureTLS Successful 5m5s ``` -We can see from the above output that the `MemcachedOpsRequest` has succeeded. +We can see from the above output that the `MemcachedOpsRequest` has succeeded. If we describe the `MemcachedOpsRequest` we will get an overview of the steps that were followed. + +```bash +$ kubectl describe mcops -n demo mc-ops-rotate +Name: mc-ops-rotate +Namespace: demo +Labels: +Annotations: +API Version: ops.kubedb.com/v1alpha1 +Kind: MemcachedOpsRequest +Metadata: + Creation Timestamp: 2024-11-18T06:14:21Z + Generation: 1 + Resource Version: 1802316 + UID: 0c54644b-3006-4c3d-8c12-4566ad73a7eb +Spec: + Apply: IfReady + Database Ref: + Name: memcd-quickstart + Tls: + Rotate Certificates: true + Type: ReconfigureTLS +Status: + Conditions: + Last Transition Time: 2024-11-18T06:14:21Z + Message: Memcached ops request is reconfiguring TLS + Observed Generation: 1 + Reason: ReconfigureTLS + Status: True + Type: ReconfigureTLS + Last Transition Time: 2024-11-18T06:14:24Z + Message: successfully add issuing condition to all the certificates + Observed Generation: 1 + Reason: IssueCertificatesSucceeded + Status: True + Type: IssueCertificatesSucceeded + Last Transition Time: 2024-11-18T06:14:35Z + Message: Successfully synced all certificates + Observed Generation: 1 + Reason: CertificateSynced + Status: True + Type: CertificateSynced + Last Transition Time: 2024-11-18T06:14:29Z + Message: get certificate; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: GetCertificate + Last Transition Time: 2024-11-18T06:14:29Z + Message: check ready condition; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: CheckReadyCondition + Last Transition Time: 2024-11-18T06:14:29Z + Message: check issuing condition; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: CheckIssuingCondition + Last Transition Time: 2024-11-18T06:14:55Z + Message: Successfully restarted pods + Observed Generation: 1 + Reason: RestartPods + Status: True + Type: RestartPods + Last Transition Time: 2024-11-18T06:14:40Z + Message: evict pod; ConditionStatus:True; PodName:memcd-quickstart-0 + Observed Generation: 1 + Status: True + Type: EvictPod--memcd-quickstart-0 + Last Transition Time: 2024-11-18T06:14:40Z + Message: is pod ready; ConditionStatus:False + Observed Generation: 1 + Status: False + Type: IsPodReady + Last Transition Time: 2024-11-18T06:14:45Z + Message: is pod ready; ConditionStatus:True; PodName:memcd-quickstart-0 + Observed Generation: 1 + Status: True + Type: IsPodReady--memcd-quickstart-0 + Last Transition Time: 2024-11-18T06:14:45Z + Message: Successfully reconfigured TLS + Observed Generation: 1 + Reason: Successful + Status: True + Type: Successful + Observed Generation: 1 + Phase: Successful +Events: + +``` + +Now, let’s check the expiration date of the certificate: +```bash +$ kubectl port-forward -n demo memcd-quickstart-0 11211 +Forwarding from 127.0.0.1:11211 -> 11211 +Forwarding from [::1]:11211 -> 11211 + +$ openssl x509 -in <(openssl s_client -connect 127.0.0.1:11211 -showcerts < /dev/null 2>/dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p') -noout -enddate +notAfter=Feb 16 06:46:16 2025 GMT +``` +As we can see from the above output, the certificate has been rotated successfully as the expire time got updated. ## Change Issuer/ClusterIssuer @@ -427,7 +625,138 @@ NAME TYPE STATUS AGE mc-change-issuer ReconfigureTLS Successful 4m65s ``` -We can see from the above output that the `MemcachedOpsRequest` has succeeded. +We can see from the above output that the `MemcachedlOpsRequest` has succeeded. If we describe the `MemcachedOpsRequest` we will get an overview of the steps that were followed. + +```bash +$ kubectl describe mcops -n demo mc-change-issuer +Name: mc-change-issuer +Namespace: demo +Labels: +Annotations: +API Version: ops.kubedb.com/v1alpha1 +Kind: MemcachedOpsRequest +Metadata: + Creation Timestamp: 2024-11-18T11:26:45Z + Generation: 1 + Resource Version: 1830164 + UID: 9d1e3477-7b22-4feb-8e32-97cd33c8b312 +Spec: + Apply: IfReady + Database Ref: + Name: memcd-quickstart + Tls: + Issuer Ref: + API Group: cert-manager.io + Kind: Issuer + Name: my-new-issuer + Type: ReconfigureTLS +Status: + Conditions: + Last Transition Time: 2024-11-18T11:26:45Z + Message: Memcached ops request is reconfiguring TLS + Observed Generation: 1 + Reason: ReconfigureTLS + Status: True + Type: ReconfigureTLS + Last Transition Time: 2024-11-18T11:26:58Z + Message: Successfully synced all certificates + Observed Generation: 1 + Reason: CertificateSynced + Status: True + Type: CertificateSynced + Last Transition Time: 2024-11-18T11:26:53Z + Message: get certificate; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: GetCertificate + Last Transition Time: 2024-11-18T11:26:53Z + Message: check ready condition; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: CheckReadyCondition + Last Transition Time: 2024-11-18T11:26:53Z + Message: check issuing condition; ConditionStatus:True + Observed Generation: 1 + Status: True + Type: CheckIssuingCondition + Last Transition Time: 2024-11-18T11:27:18Z + Message: Successfully restarted pods + Observed Generation: 1 + Reason: RestartPods + Status: True + Type: RestartPods + Last Transition Time: 2024-11-18T11:27:03Z + Message: evict pod; ConditionStatus:True; PodName:memcd-quickstart-0 + Observed Generation: 1 + Status: True + Type: EvictPod--memcd-quickstart-0 + Last Transition Time: 2024-11-18T11:27:03Z + Message: is pod ready; ConditionStatus:False + Observed Generation: 1 + Status: False + Type: IsPodReady + Last Transition Time: 2024-11-18T11:27:08Z + Message: is pod ready; ConditionStatus:True; PodName:memcd-quickstart-0 + Observed Generation: 1 + Status: True + Type: IsPodReady--memcd-quickstart-0 + Last Transition Time: 2024-11-18T11:27:08Z + Message: Successfully reconfigured TLS + Observed Generation: 1 + Reason: Successful + Status: True + Type: Successful + Observed Generation: 1 + Phase: Successful +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal PauseDatabase 16m KubeDB Ops-manager Operator Pausing Memcached demo/memcd-quickstart + Warning get certificate; ConditionStatus:True 16m KubeDB Ops-manager Operator get certificate; ConditionStatus:True + Warning check ready condition; ConditionStatus:True 16m KubeDB Ops-manager Operator check ready condition; ConditionStatus:True + Warning check issuing condition; ConditionStatus:True 16m KubeDB Ops-manager Operator check issuing condition; ConditionStatus:True + Warning get certificate; ConditionStatus:True 16m KubeDB Ops-manager Operator get certificate; ConditionStatus:True + Warning check ready condition; ConditionStatus:True 16m KubeDB Ops-manager Operator check ready condition; ConditionStatus:True + Warning check issuing condition; ConditionStatus:True 16m KubeDB Ops-manager Operator check issuing condition; ConditionStatus:True + Warning get certificate; ConditionStatus:True 16m KubeDB Ops-manager Operator get certificate; ConditionStatus:True + Warning check ready condition; ConditionStatus:True 16m KubeDB Ops-manager Operator check ready condition; ConditionStatus:True + Warning check issuing condition; ConditionStatus:True 16m KubeDB Ops-manager Operator check issuing condition; ConditionStatus:True + Normal CertificateSynced 16m KubeDB Ops-manager Operator Successfully synced all certificates + Warning get certificate; ConditionStatus:True 16m KubeDB Ops-manager Operator get certificate; ConditionStatus:True + Warning check ready condition; ConditionStatus:True 16m KubeDB Ops-manager Operator check ready condition; ConditionStatus:True + Warning check issuing condition; ConditionStatus:True 16m KubeDB Ops-manager Operator check issuing condition; ConditionStatus:True + Warning get certificate; ConditionStatus:True 16m KubeDB Ops-manager Operator get certificate; ConditionStatus:True + Warning check ready condition; ConditionStatus:True 16m KubeDB Ops-manager Operator check ready condition; ConditionStatus:True + Warning check issuing condition; ConditionStatus:True 16m KubeDB Ops-manager Operator check issuing condition; ConditionStatus:True + Warning get certificate; ConditionStatus:True 16m KubeDB Ops-manager Operator get certificate; ConditionStatus:True + Warning check ready condition; ConditionStatus:True 16m KubeDB Ops-manager Operator check ready condition; ConditionStatus:True + Warning check issuing condition; ConditionStatus:True 16m KubeDB Ops-manager Operator check issuing condition; ConditionStatus:True + Normal CertificateSynced 16m KubeDB Ops-manager Operator Successfully synced all certificates + Warning evict pod; ConditionStatus:True; PodName:memcd-quickstart-0 16m KubeDB Ops-manager Operator evict pod; ConditionStatus:True; PodName:memcd-quickstart-0 + Warning is pod ready; ConditionStatus:False 16m KubeDB Ops-manager Operator is pod ready; ConditionStatus:False + Warning is pod ready; ConditionStatus:True; PodName:memcd-quickstart-0 16m KubeDB Ops-manager Operator is pod ready; ConditionStatus:True; PodName:memcd-quickstart-0 + Normal RestartPods 16m KubeDB Ops-manager Operator Successfully restarted pods + Normal ResumeDatabase 16m KubeDB Ops-manager Operator Resuming Memcached demo/memcd-quickstart + Normal ResumeDatabase 16m KubeDB Ops-manager Operator Successfully resumed Memcached demo/memcd-quickstart + Normal Successful 16m KubeDB Ops-manager Operator Successfully Reconfigured TLS + Normal PauseDatabase 16m KubeDB Ops-manager Operator Pausing Memcached demo/memcd-quickstart + Warning evict pod; ConditionStatus:True; PodName:memcd-quickstart-0 15m KubeDB Ops-manager Operator evict pod; ConditionStatus:True; PodName:memcd-quickstart-0 + Warning is pod ready; ConditionStatus:False 15m KubeDB Ops-manager Operator is pod ready; ConditionStatus:False + Warning is pod ready; ConditionStatus:True; PodName:memcd-quickstart-0 15m KubeDB Ops-manager Operator is pod ready; ConditionStatus:True; PodName:memcd-quickstart-0 + Normal RestartPods 15m KubeDB Ops-manager Operator Successfully restarted pods +``` + +Now, let’s port-forward the database pod and find out the ca subject to see if it matches the one we have provided. + +```bash +$ kubectl port-forward -n demo memcd-quickstart-0 11211 +Forwarding from 127.0.0.1:11211 -> 11211 +Forwarding from [::1]:11211 -> 11211 + +$ openssl x509 -in <(openssl s_client -connect 127.0.0.1:11211 -showcerts < /dev/null 2>/dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p') -inform PEM -issuer -nameopt RFC2253 -noout +issuer=O=kubedb-updated,CN=memcached-updated +``` +We can see from the above output that, the subject name matches the subject name of the new ca certificate that we have created. So, the issuer is changed successfully. ## Remove TLS from the Database @@ -475,8 +804,67 @@ NAME TYPE STATUS AGE mc-ops-remove ReconfigureTLS Successful 105s ``` -We can see from the above output that the `MemcachedOpsRequest` has succeeded. +We can see from the above output that the `MemcachedOpsRequest` has succeeded. If we describe the `MemcachedOpsRequest` we will get an overview of the steps that were followed. +```bash +$ kubectl describe mcops -n demo mc-ops-remove +Name: mc-ops-remove +Namespace: demo +Labels: +Annotations: +API Version: ops.kubedb.com/v1alpha1 +Kind: MemcachedOpsRequest +Metadata: + Creation Timestamp: 2024-11-12T12:49:09Z + Generation: 1 + Resource Version: 1684823 + UID: c3260cc6-7862-4f22-9e12-93dcdb3edac8 +Spec: + Apply: IfReady + Database Ref: + Name: memcd-quickstart + Tls: + Remove: true + Type: ReconfigureTLS +Status: + Conditions: + Last Transition Time: 2024-11-12T12:49:09Z + Message: Memcached ops request is reconfiguring TLS + Observed Generation: 1 + Reason: ReconfigureTLS + Status: True + Type: ReconfigureTLS + Last Transition Time: 2024-11-12T12:49:32Z + Message: Successfully restarted pods + Observed Generation: 1 + Reason: RestartPods + Status: True + Type: RestartPods + Last Transition Time: 2024-11-12T12:49:17Z + Message: evict pod; ConditionStatus:True; PodName:memcd-quickstart-0 + Observed Generation: 1 + Status: True + Type: EvictPod--memcd-quickstart-0 + Last Transition Time: 2024-11-12T12:49:17Z + Message: is pod ready; ConditionStatus:False + Observed Generation: 1 + Status: False + Type: IsPodReady + Last Transition Time: 2024-11-12T12:49:22Z + Message: is pod ready; ConditionStatus:True; PodName:memcd-quickstart-0 + Observed Generation: 1 + Status: True + Type: IsPodReady--memcd-quickstart-0 + Last Transition Time: 2024-11-12T12:49:32Z + Message: Successfully reconfigured TLS + Observed Generation: 1 + Reason: Successful + Status: True + Type: Successful + Observed Generation: 1 + Phase: Successful +Events: +``` Now, Lets check Memcached TLS is disabled or not. ```bash From 87ac1f64db9c929b45fa819bbb99fe38ea6e2482 Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Mon, 18 Nov 2024 18:24:39 +0600 Subject: [PATCH 06/12] Add Yamls Signed-off-by: Muhammad Raisul Islam Evan --- .../memcached/reconfigure-tls/issuer.yaml | 8 +++++++ .../memcached/reconfigure-tls/mc-add-tls.yaml | 21 +++++++++++++++++++ .../reconfigure-tls/mc-change-issuer.yaml | 14 +++++++++++++ .../reconfigure-tls/mc-new-issuer.yaml | 8 +++++++ .../reconfigure-tls/mc-ops-rotate.yaml | 11 ++++++++++ .../reconfigure-tls/mc-ops-tls-remove.yaml | 11 ++++++++++ .../memcached/reconfigure-tls/memcached.yaml | 9 ++++++++ docs/examples/memcached/tls/mc-tls.yaml | 19 +++++++++++++++++ .../memcached/tls/memcached-ca-issuer.yaml | 8 +++++++ .../reconfigure-tls/reconfigure-tls.md | 18 ++++++++-------- 10 files changed, 118 insertions(+), 9 deletions(-) create mode 100644 docs/examples/memcached/reconfigure-tls/issuer.yaml create mode 100644 docs/examples/memcached/reconfigure-tls/mc-add-tls.yaml create mode 100644 docs/examples/memcached/reconfigure-tls/mc-change-issuer.yaml create mode 100644 docs/examples/memcached/reconfigure-tls/mc-new-issuer.yaml create mode 100644 docs/examples/memcached/reconfigure-tls/mc-ops-rotate.yaml create mode 100644 docs/examples/memcached/reconfigure-tls/mc-ops-tls-remove.yaml create mode 100644 docs/examples/memcached/reconfigure-tls/memcached.yaml create mode 100644 docs/examples/memcached/tls/mc-tls.yaml create mode 100644 docs/examples/memcached/tls/memcached-ca-issuer.yaml diff --git a/docs/examples/memcached/reconfigure-tls/issuer.yaml b/docs/examples/memcached/reconfigure-tls/issuer.yaml new file mode 100644 index 0000000000..3b1e28f714 --- /dev/null +++ b/docs/examples/memcached/reconfigure-tls/issuer.yaml @@ -0,0 +1,8 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: memcached-ca-issuer + namespace: demo +spec: + ca: + secretName: memcached-ca \ No newline at end of file diff --git a/docs/examples/memcached/reconfigure-tls/mc-add-tls.yaml b/docs/examples/memcached/reconfigure-tls/mc-add-tls.yaml new file mode 100644 index 0000000000..9dee52dfd0 --- /dev/null +++ b/docs/examples/memcached/reconfigure-tls/mc-add-tls.yaml @@ -0,0 +1,21 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: MemcachedOpsRequest +metadata: + name: mc-add-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: memcd-quickstart + tls: + issuerRef: + name: memcached-ca-issuer + kind: Issuer + apiGroup: "cert-manager.io" + certificates: + - alias: client + subject: + organizations: + - memcached + organizationalUnits: + - client \ No newline at end of file diff --git a/docs/examples/memcached/reconfigure-tls/mc-change-issuer.yaml b/docs/examples/memcached/reconfigure-tls/mc-change-issuer.yaml new file mode 100644 index 0000000000..2da1192df0 --- /dev/null +++ b/docs/examples/memcached/reconfigure-tls/mc-change-issuer.yaml @@ -0,0 +1,14 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: MemcachedOpsRequest +metadata: + name: mc-change-issuer + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: memcd-quickstart + tls: + issuerRef: + name: mc-new-issuer + kind: Issuer + apiGroup: "cert-manager.io" \ No newline at end of file diff --git a/docs/examples/memcached/reconfigure-tls/mc-new-issuer.yaml b/docs/examples/memcached/reconfigure-tls/mc-new-issuer.yaml new file mode 100644 index 0000000000..4d9bd4fa1b --- /dev/null +++ b/docs/examples/memcached/reconfigure-tls/mc-new-issuer.yaml @@ -0,0 +1,8 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: mc-new-issuer + namespace: demo +spec: + ca: + secretName: memcached-new-ca \ No newline at end of file diff --git a/docs/examples/memcached/reconfigure-tls/mc-ops-rotate.yaml b/docs/examples/memcached/reconfigure-tls/mc-ops-rotate.yaml new file mode 100644 index 0000000000..095ca9ee75 --- /dev/null +++ b/docs/examples/memcached/reconfigure-tls/mc-ops-rotate.yaml @@ -0,0 +1,11 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: MemcachedOpsRequest +metadata: + name: mc-ops-rotate + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: memcd-quickstart + tls: + rotateCertificates: true \ No newline at end of file diff --git a/docs/examples/memcached/reconfigure-tls/mc-ops-tls-remove.yaml b/docs/examples/memcached/reconfigure-tls/mc-ops-tls-remove.yaml new file mode 100644 index 0000000000..fb5f6f80e2 --- /dev/null +++ b/docs/examples/memcached/reconfigure-tls/mc-ops-tls-remove.yaml @@ -0,0 +1,11 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: MemcachedOpsRequest +metadata: + name: mc-ops-tls-remove + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: memcd-quickstart + tls: + remove: true \ No newline at end of file diff --git a/docs/examples/memcached/reconfigure-tls/memcached.yaml b/docs/examples/memcached/reconfigure-tls/memcached.yaml new file mode 100644 index 0000000000..405c5f6bf8 --- /dev/null +++ b/docs/examples/memcached/reconfigure-tls/memcached.yaml @@ -0,0 +1,9 @@ +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + name: memcd-quickstart + namespace: demo +spec: + replicas: 1 + version: "1.6.22" + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/examples/memcached/tls/mc-tls.yaml b/docs/examples/memcached/tls/mc-tls.yaml new file mode 100644 index 0000000000..d6f6457d80 --- /dev/null +++ b/docs/examples/memcached/tls/mc-tls.yaml @@ -0,0 +1,19 @@ +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + name: memcd-quickstart + namespace: demo +spec: + replicas: 1 + version: "1.6.22" + tls: + issuerRef: + apiGroup: "cert-manager.io" + kind: Issuer + name: memcached-ca-issuer + certificates: + - alias: client + ipAddresses: + - 127.0.0.1 + - 192.168.0.252 + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/examples/memcached/tls/memcached-ca-issuer.yaml b/docs/examples/memcached/tls/memcached-ca-issuer.yaml new file mode 100644 index 0000000000..3b1e28f714 --- /dev/null +++ b/docs/examples/memcached/tls/memcached-ca-issuer.yaml @@ -0,0 +1,8 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: memcached-ca-issuer + namespace: demo +spec: + ca: + secretName: memcached-ca \ No newline at end of file diff --git a/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md b/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md index 001eada0e5..9f17289e0b 100644 --- a/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md @@ -198,7 +198,7 @@ Let's create the `MemcachedOpsRequest` CR we have shown above, ```bash $ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/reconfigure-tls/mc-add-tls.yaml -Memcachedopsrequest.ops.kubedb.com/rd-add-tls created +Memcachedopsrequest.ops.kubedb.com/mc-add-tls created ``` #### Verify TLS Enabled Successfully @@ -401,7 +401,7 @@ Now we are going to rotate certificates using a MemcachedOpsRequest. Below is th apiVersion: ops.kubedb.com/v1alpha1 kind: MemcachedOpsRequest metadata: - name: myops-rotate + name: mc-ops-rotate namespace: demo spec: type: ReconfigureTLS @@ -576,7 +576,7 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/reconfigure-tls/new-issuer.yaml +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/reconfigure-tls/mc-new-issuer.yaml issuer.cert-manager.io/mc-new-issuer created ``` @@ -770,7 +770,7 @@ Below is the YAML of the `MemcachedOpsRequest` CRO that we are going to create, apiVersion: ops.kubedb.com/v1alpha1 kind: MemcachedOpsRequest metadata: - name: mc-ops-remove + name: mc-ops-tls-remove namespace: demo spec: type: ReconfigureTLS @@ -789,7 +789,7 @@ Here, Let's create the `MemcachedOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/reconfigure-tls/mc-ops-remove.yaml +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/reconfigure-tls/mc-ops-tls-remove.yaml Memcachedopsrequest.ops.kubedb.com/mc-ops-remove created ``` @@ -800,15 +800,15 @@ Let's wait for `MemcachedOpsRequest` to be `Successful`. Run the following comm ```bash $ kubectl get memcachedopsrequest -n demo Every 2.0s: kubectl get memcachedopsrequest -n demo -NAME TYPE STATUS AGE -mc-ops-remove ReconfigureTLS Successful 105s +NAME TYPE STATUS AGE +mc-ops-tls-remove ReconfigureTLS Successful 105s ``` We can see from the above output that the `MemcachedOpsRequest` has succeeded. If we describe the `MemcachedOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mcops -n demo mc-ops-remove -Name: mc-ops-remove +$ kubectl describe mcops -n demo mc-ops-tls-remove +Name: mc-ops-tls-remove Namespace: demo Labels: Annotations: From a583895a1279835a2524d6b2dad994cd06b1cfa0 Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Tue, 19 Nov 2024 11:22:14 +0600 Subject: [PATCH 07/12] Fix _index.md files Signed-off-by: Muhammad Raisul Islam Evan --- docs/guides/memcached/reconfigure-tls/_index.md | 2 +- docs/guides/memcached/reconfigure-tls/overview.md | 2 +- docs/guides/memcached/reconfigure-tls/reconfigure-tls.md | 6 +++--- docs/guides/memcached/restart/_index.md | 2 +- docs/guides/memcached/restart/restart.md | 2 +- docs/guides/memcached/tls/_index.md | 2 +- docs/guides/memcached/tls/overview.md | 2 +- docs/guides/memcached/tls/tls.md | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/guides/memcached/reconfigure-tls/_index.md b/docs/guides/memcached/reconfigure-tls/_index.md index a06a6b45a7..5d37080cf1 100644 --- a/docs/guides/memcached/reconfigure-tls/_index.md +++ b/docs/guides/memcached/reconfigure-tls/_index.md @@ -2,7 +2,7 @@ title: Reconfigure Memcached TLS/SSL menu: docs_{{ .version }}: - identifier: mc-reconfigure-tls + identifier: reconfigure-tls name: Reconfigure TLS/SSL parent: mc-memcached-guides weight: 46 diff --git a/docs/guides/memcached/reconfigure-tls/overview.md b/docs/guides/memcached/reconfigure-tls/overview.md index 07f961b238..1e1722db37 100644 --- a/docs/guides/memcached/reconfigure-tls/overview.md +++ b/docs/guides/memcached/reconfigure-tls/overview.md @@ -4,7 +4,7 @@ menu: docs_{{ .version }}: identifier: mc-reconfigure-tls-overview name: Overview - parent: mc-reconfigure-tls + parent: reconfigure-tls weight: 10 menu_name: docs_{{ .version }} section_menu_id: guides diff --git a/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md b/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md index 9f17289e0b..ca57ecd65f 100644 --- a/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md @@ -2,9 +2,9 @@ title: Reconfigure Memcached TLS/SSL Encryption menu: docs_{{ .version }}: - identifier: mc-reconfigure-tls-standalone - name: Memcahced Reconfigure TLS - parent: mc-reconfigure-tls + identifier: mc-reconfigure-tls + name: Reconfigure TLS + parent: reconfigure-tls weight: 20 menu_name: docs_{{ .version }} section_menu_id: guides diff --git a/docs/guides/memcached/restart/_index.md b/docs/guides/memcached/restart/_index.md index 2c6c316493..dbed8c5e55 100644 --- a/docs/guides/memcached/restart/_index.md +++ b/docs/guides/memcached/restart/_index.md @@ -2,7 +2,7 @@ title: Restart Memcached menu: docs_{{ .version }}: - identifier: restart + identifier: mc-restart name: Restart parent: mc-memcached-guides weight: 46 diff --git a/docs/guides/memcached/restart/restart.md b/docs/guides/memcached/restart/restart.md index 85ea8c3f04..99d715660a 100644 --- a/docs/guides/memcached/restart/restart.md +++ b/docs/guides/memcached/restart/restart.md @@ -4,7 +4,7 @@ menu: docs_{{ .version }}: identifier: mc-restart name: Restart - parent: TLS/SSL Encryption + parent: mc-restart weight: 10 menu_name: docs_{{ .version }} section_menu_id: guides diff --git a/docs/guides/memcached/tls/_index.md b/docs/guides/memcached/tls/_index.md index 83882bc4aa..81398d5ecf 100644 --- a/docs/guides/memcached/tls/_index.md +++ b/docs/guides/memcached/tls/_index.md @@ -2,7 +2,7 @@ title: Run Memcached with TLS menu: docs_{{ .version }}: - identifier: mc-tls + identifier: tls name: TLS/SSL Encryption parent: mc-memcached-guides weight: 45 diff --git a/docs/guides/memcached/tls/overview.md b/docs/guides/memcached/tls/overview.md index 485402db16..3e88c8b1c9 100644 --- a/docs/guides/memcached/tls/overview.md +++ b/docs/guides/memcached/tls/overview.md @@ -4,7 +4,7 @@ menu: docs_{{ .version }}: identifier: mc-tls-overview name: Overview - parent: mc-tls + parent: tls weight: 10 menu_name: docs_{{ .version }} section_menu_id: guides diff --git a/docs/guides/memcached/tls/tls.md b/docs/guides/memcached/tls/tls.md index 7c9f5de31a..33261984f3 100644 --- a/docs/guides/memcached/tls/tls.md +++ b/docs/guides/memcached/tls/tls.md @@ -4,7 +4,7 @@ menu: docs_{{ .version }}: identifier: mc-tls name: TLS - parent: mc-tls + parent: tls weight: 20 menu_name: docs_{{ .version }} section_menu_id: guides From 0bdc1af50a408b2e6a34e060adca790459889324 Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Tue, 19 Nov 2024 14:40:48 +0600 Subject: [PATCH 08/12] Fix readme.md and index Signed-off-by: Muhammad Raisul Islam Evan --- docs/guides/memcached/README.md | 46 ++++++++++++------------ docs/guides/memcached/restart/_index.md | 2 +- docs/guides/memcached/restart/restart.md | 2 +- docs/guides/memcached/tls/tls.md | 2 +- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/docs/guides/memcached/README.md b/docs/guides/memcached/README.md index 3c8e416161..b3cc894775 100644 --- a/docs/guides/memcached/README.md +++ b/docs/guides/memcached/README.md @@ -15,32 +15,30 @@ aliases: > New to KubeDB? Please start [here](/docs/README.md). +## Overview +Memcached is an in-memory key-value store that allows for high-performance, low-latency data caching. It is often used to speed up dynamic web applications by offloading frequent, computationally expensive database queries and storing data that needs to be retrieved fast. Memcached is frequently used in contexts where the rapid retrieval of tiny data items, such as session data, query results, and user profiles, is critical for increasing application performance. It is especially well-suited for use cases requiring scalability, distributed caching, and high throughput, making it a popular choice for powering online and mobile apps, particularly in high-concurrency environments. Memcached is a simple, extremely efficient caching layer that minimizes stress on backend systems and improves performance for applications that require real-time data. + ## Supported Memcached Features -| Features | Availability | -| ------------------------------------ | :----------: | -| Clustering | ✗ | -| Persistent Volume | ✗ | -| Instant Backup | ✗ | -| Scheduled Backup | ✗ | -| Initialize using Snapshot | ✗ | -| Initialize using Script | ✗ | -| Multiple Memcached Versions | ✓ | -| Custom Configuration | ✓ | -| Externally manageable Auth Secret | ✗ | -| Reconfigurable Health Checker | ✓ | -| Using Custom docker image | ✓ | -| Builtin Prometheus Discovery | ✓ | -| Using Prometheus operator | ✓ | -| Automated Version Update | ✓ | -| Automated Vertical Scaling | ✓ | -| Automated Horizontal Scaling | ✓ | -| Automated db-configure Reconfiguration | ✓ | -| TLS: Add, Remove, Update, Rotate ( Cert Manager ) |✗| -| Automated Volume Expansion | ✗ | -| Autoscaling (Vertically) | ✓ | -| Grafana Dashboard | ✓ | -| Alert Dashboard | ✗ | +| Features | Availability | +| ----------------------------------------------------- | :----------: | +| Multiple Memcached Versions | ✓ | +| Custom Configuration | ✓ | +| Externally manageable Auth Secret | ✓ | +| Reconfigurable Health Checker | ✓ | +| Using Custom docker image | ✓ | +| Builtin Prometheus Discovery | ✓ | +| Using Prometheus operator | ✓ | +| Automated Version Update | ✓ | +| Automated Vertical Scaling | ✓ | +| Automated Horizontal Scaling | ✓ | +| Automated db-configure Reconfiguration | ✓ | +| Authentication & Authorization | ✓ | +| TLS: Add, Remove, Update, Rotate ( Cert Manager ) | ✓ | +| Autoscaling (Vertically) | ✓ | +| Monitoring using Prometheus and Grafana | ✓ | +| Monitoring Grafana Dashboard | ✓ | +| Alert Grafana Dashboard | ✓ | diff --git a/docs/guides/memcached/restart/_index.md b/docs/guides/memcached/restart/_index.md index dbed8c5e55..2c6c316493 100644 --- a/docs/guides/memcached/restart/_index.md +++ b/docs/guides/memcached/restart/_index.md @@ -2,7 +2,7 @@ title: Restart Memcached menu: docs_{{ .version }}: - identifier: mc-restart + identifier: restart name: Restart parent: mc-memcached-guides weight: 46 diff --git a/docs/guides/memcached/restart/restart.md b/docs/guides/memcached/restart/restart.md index 99d715660a..3a9a448883 100644 --- a/docs/guides/memcached/restart/restart.md +++ b/docs/guides/memcached/restart/restart.md @@ -4,7 +4,7 @@ menu: docs_{{ .version }}: identifier: mc-restart name: Restart - parent: mc-restart + parent: restart weight: 10 menu_name: docs_{{ .version }} section_menu_id: guides diff --git a/docs/guides/memcached/tls/tls.md b/docs/guides/memcached/tls/tls.md index 33261984f3..8a47c84576 100644 --- a/docs/guides/memcached/tls/tls.md +++ b/docs/guides/memcached/tls/tls.md @@ -3,7 +3,7 @@ title: Memcached TLS/SSL Encryption menu: docs_{{ .version }}: identifier: mc-tls - name: TLS + name: TLS/SSL parent: tls weight: 20 menu_name: docs_{{ .version }} From 751bd7c2a45e93c2da94a432db6a90a15bcd2005 Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Mon, 2 Dec 2024 19:56:23 +0600 Subject: [PATCH 09/12] Add Memcached custom-podTemplate Signed-off-by: Muhammad Raisul Islam Evan --- .../custom-config/custom-podtemplate.yaml | 18 + .../custom-config/node-selector.yaml | 13 + .../custom-config/sidecar-container.yaml | 29 + .../custom-config/without-toleration.yaml | 9 + docs/guides/memcached/README.md | 8 +- docs/guides/memcached/autoscaler/_index.md | 2 +- .../memcached/autoscaler/compute/_index.md | 2 +- docs/guides/memcached/cli/cli.md | 2 +- docs/guides/memcached/concepts/_index.md | 2 +- docs/guides/memcached/concepts/memcached.md | 2 +- .../memcached/custom-configuration/_index.md | 2 +- .../custom-configuration/using-config-file.md | 2 +- .../custom-configuration/using-podtemplate.md | 600 ++++++++++++++++++ docs/guides/memcached/monitoring/_index.md | 2 +- .../monitoring/using-prometheus-operator.md | 9 +- docs/guides/memcached/quickstart/_index.md | 2 +- .../memcached/reconfigure-tls/_index.md | 2 +- .../reconfigure-tls/reconfigure-tls.md | 10 +- docs/guides/memcached/reconfigure/_index.md | 2 +- docs/guides/memcached/restart/_index.md | 2 +- docs/guides/memcached/scaling/_index.md | 2 +- docs/guides/memcached/tls/_index.md | 2 +- docs/guides/memcached/tls/tls.md | 20 +- .../guides/memcached/update-version/_index.md | 2 +- .../memcached-prometheus-operator.png | Bin 0 -> 54920 bytes 25 files changed, 715 insertions(+), 31 deletions(-) create mode 100644 docs/examples/memcached/custom-config/custom-podtemplate.yaml create mode 100644 docs/examples/memcached/custom-config/node-selector.yaml create mode 100644 docs/examples/memcached/custom-config/sidecar-container.yaml create mode 100644 docs/examples/memcached/custom-config/without-toleration.yaml create mode 100644 docs/guides/memcached/custom-configuration/using-podtemplate.md create mode 100644 docs/images/memcached/monitoring/memcached-prometheus-operator.png diff --git a/docs/examples/memcached/custom-config/custom-podtemplate.yaml b/docs/examples/memcached/custom-config/custom-podtemplate.yaml new file mode 100644 index 0000000000..3f055e438d --- /dev/null +++ b/docs/examples/memcached/custom-config/custom-podtemplate.yaml @@ -0,0 +1,18 @@ +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + name: custom-mc + namespace: demo +spec: + version: "1.6.22" + replicas: 1 + podTemplate: + spec: + containers: + - name: memcached + env: + - name: "Memcached_Key" + value: KubeDB + - name: "Memcached_Value" + value: '123' + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/examples/memcached/custom-config/node-selector.yaml b/docs/examples/memcached/custom-config/node-selector.yaml new file mode 100644 index 0000000000..6dce584cc7 --- /dev/null +++ b/docs/examples/memcached/custom-config/node-selector.yaml @@ -0,0 +1,13 @@ +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + name: memcached-node-selector + namespace: demo +spec: + version: "1.6.22" + replicas: 1 + podTemplate: + spec: + nodeSelector: + disktype: ssd + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/examples/memcached/custom-config/sidecar-container.yaml b/docs/examples/memcached/custom-config/sidecar-container.yaml new file mode 100644 index 0000000000..8d0dcc2bbe --- /dev/null +++ b/docs/examples/memcached/custom-config/sidecar-container.yaml @@ -0,0 +1,29 @@ +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + name: memcached-custom-sidecar + namespace: demo +spec: + version: "1.6.22" + replicas: 1 + podTemplate: + spec: + containers: + - name: memcached + resources: + limits: + cpu: 100m + memory: 100Mi + requests: + cpu: 100m + memory: 100Mi + - name: filebeat + image: evanraisul/custom_filebeat:latest + resources: + limits: + cpu: 300m + memory: 300Mi + requests: + cpu: 300m + memory: 300Mi + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/examples/memcached/custom-config/without-toleration.yaml b/docs/examples/memcached/custom-config/without-toleration.yaml new file mode 100644 index 0000000000..880db1eedb --- /dev/null +++ b/docs/examples/memcached/custom-config/without-toleration.yaml @@ -0,0 +1,9 @@ +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + name: memcached-without-tolerations + namespace: demo +spec: + version: "1.6.22" + replicas: 1 + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/guides/memcached/README.md b/docs/guides/memcached/README.md index b3cc894775..d493889cbc 100644 --- a/docs/guides/memcached/README.md +++ b/docs/guides/memcached/README.md @@ -16,19 +16,18 @@ aliases: > New to KubeDB? Please start [here](/docs/README.md). ## Overview -Memcached is an in-memory key-value store that allows for high-performance, low-latency data caching. It is often used to speed up dynamic web applications by offloading frequent, computationally expensive database queries and storing data that needs to be retrieved fast. Memcached is frequently used in contexts where the rapid retrieval of tiny data items, such as session data, query results, and user profiles, is critical for increasing application performance. It is especially well-suited for use cases requiring scalability, distributed caching, and high throughput, making it a popular choice for powering online and mobile apps, particularly in high-concurrency environments. Memcached is a simple, extremely efficient caching layer that minimizes stress on backend systems and improves performance for applications that require real-time data. +`Memcached` is an in-memory key-value store that allows for high-performance, low-latency data caching. It is often used to speed up dynamic web applications by offloading frequent, computationally expensive database queries and storing data that needs to be retrieved fast. Memcached is frequently used in contexts where the rapid retrieval of tiny data items, such as session data, query results, and user profiles, is critical for increasing application performance. It is especially well-suited for use cases requiring scalability, distributed caching, and high throughput, making it a popular choice for powering online and mobile apps, particularly in high-concurrency environments. Memcached is a simple, extremely efficient caching layer that minimizes stress on backend systems and improves performance for applications that require real-time data. ## Supported Memcached Features | Features | Availability | | ----------------------------------------------------- | :----------: | -| Multiple Memcached Versions | ✓ | | Custom Configuration | ✓ | | Externally manageable Auth Secret | ✓ | | Reconfigurable Health Checker | ✓ | | Using Custom docker image | ✓ | | Builtin Prometheus Discovery | ✓ | -| Using Prometheus operator | ✓ | +| Operator Managed Prometheus Discovery | ✓ | | Automated Version Update | ✓ | | Automated Vertical Scaling | ✓ | | Automated Horizontal Scaling | ✓ | @@ -36,12 +35,11 @@ Memcached is an in-memory key-value store that allows for high-performance, low- | Authentication & Authorization | ✓ | | TLS: Add, Remove, Update, Rotate ( Cert Manager ) | ✓ | | Autoscaling (Vertically) | ✓ | +| Multiple Memcached Versions | ✓ | | Monitoring using Prometheus and Grafana | ✓ | | Monitoring Grafana Dashboard | ✓ | | Alert Grafana Dashboard | ✓ | - - ## Life Cycle of a Memcached Object

diff --git a/docs/guides/memcached/autoscaler/_index.md b/docs/guides/memcached/autoscaler/_index.md index 58da1969e7..098776c881 100644 --- a/docs/guides/memcached/autoscaler/_index.md +++ b/docs/guides/memcached/autoscaler/_index.md @@ -5,6 +5,6 @@ menu: identifier: auto-scaling name: Autoscaling parent: mc-memcached-guides - weight: 47 + weight: 90 menu_name: docs_{{ .version }} --- diff --git a/docs/guides/memcached/autoscaler/compute/_index.md b/docs/guides/memcached/autoscaler/compute/_index.md index 49b6502d63..05ca38c926 100644 --- a/docs/guides/memcached/autoscaler/compute/_index.md +++ b/docs/guides/memcached/autoscaler/compute/_index.md @@ -5,6 +5,6 @@ menu: identifier: compute-auto-scaling name: Compute Autoscaling parent: auto-scaling - weight: 46 + weight: 91 menu_name: docs_{{ .version }} --- diff --git a/docs/guides/memcached/cli/cli.md b/docs/guides/memcached/cli/cli.md index 41b442502f..03b700c1c1 100644 --- a/docs/guides/memcached/cli/cli.md +++ b/docs/guides/memcached/cli/cli.md @@ -292,5 +292,5 @@ $ kubectl delete memcached ## Next Steps - Learn how to use KubeDB to run a Memcached server [here](/docs/guides/memcached/README.md). -- Learn how to use custom configuration in Memcached with KubeDB [here](/docs/guides/memcached/custom-configuration/using-config-file.md) +- Learn how to use custom configuration in Memcached with KubeDB [here](/docs/guides/memcached/custom-configuration/customize-configuration) - Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). diff --git a/docs/guides/memcached/concepts/_index.md b/docs/guides/memcached/concepts/_index.md index 94d7c13bed..32458fddff 100755 --- a/docs/guides/memcached/concepts/_index.md +++ b/docs/guides/memcached/concepts/_index.md @@ -5,6 +5,6 @@ menu: identifier: mc-concepts-memcached name: Concepts parent: mc-memcached-guides - weight: 20 + weight: 30 menu_name: docs_{{ .version }} --- diff --git a/docs/guides/memcached/concepts/memcached.md b/docs/guides/memcached/concepts/memcached.md index 4a0ac57709..6fed3bf35a 100644 --- a/docs/guides/memcached/concepts/memcached.md +++ b/docs/guides/memcached/concepts/memcached.md @@ -104,7 +104,7 @@ Memcached managed by KubeDB can be monitored with builtin-Prometheus and Prometh ### spec.configSecret -`spec.configSecret` is an optional field that allows users to provide custom configuration for Memcached. This field accepts a [`VolumeSource`](https://github.com/kubernetes/api/blob/release-1.11/core/v1/types.go#L47). So you can use any Kubernetes supported volume source such as `configMap`, `secret`, `azureDisk` etc. To learn more about how to use a custom configuration file see [here](/docs/guides/memcached/custom-configuration/using-config-file.md). +`spec.configSecret` is an optional field that allows users to provide custom configuration for Memcached. This field accepts a [`VolumeSource`](https://github.com/kubernetes/api/blob/release-1.11/core/v1/types.go#L47). So you can use any Kubernetes supported volume source such as `configMap`, `secret`, `azureDisk` etc. To learn more about how to use a custom configuration file see [here](/docs/guides/memcached/custom-configuration/customize-configuration). ### spec.podTemplate diff --git a/docs/guides/memcached/custom-configuration/_index.md b/docs/guides/memcached/custom-configuration/_index.md index 4d92d60b21..85765b8eb2 100755 --- a/docs/guides/memcached/custom-configuration/_index.md +++ b/docs/guides/memcached/custom-configuration/_index.md @@ -5,6 +5,6 @@ menu: identifier: custom-configuration name: Custom Configuration parent: mc-memcached-guides - weight: 30 + weight: 40 menu_name: docs_{{ .version }} --- diff --git a/docs/guides/memcached/custom-configuration/using-config-file.md b/docs/guides/memcached/custom-configuration/using-config-file.md index 2d74454c9b..ca4d969ad8 100644 --- a/docs/guides/memcached/custom-configuration/using-config-file.md +++ b/docs/guides/memcached/custom-configuration/using-config-file.md @@ -3,7 +3,7 @@ title: Run Memcached with Custom Configuration menu: docs_{{ .version }}: identifier: mc-using-config-file-configuration - name: Config File + name: Customize Configurations parent: custom-configuration weight: 10 menu_name: docs_{{ .version }} diff --git a/docs/guides/memcached/custom-configuration/using-podtemplate.md b/docs/guides/memcached/custom-configuration/using-podtemplate.md new file mode 100644 index 0000000000..899cdaaab8 --- /dev/null +++ b/docs/guides/memcached/custom-configuration/using-podtemplate.md @@ -0,0 +1,600 @@ +--- +title: Run Memcached with Custom Configuration +menu: + docs_{{ .version }}: + identifier: mc-using-podtemplate-configuration + name: Customize PodTemplate + parent: custom-configuration + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Run Memcached with Custom PodTemplate + +KubeDB supports providing custom configuration for Memcached via [PodTemplate](/docs/guides/pgpool/concepts/pgpool.md#specpodtemplate). This tutorial will show you how to use KubeDB to run a Memcached database with custom configuration using PodTemplate. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Now, install KubeDB cli on your workstation and KubeDB operator in your cluster following the steps [here](/docs/setup/README.md). + +- To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. + + ```bash + $ kubectl create ns demo + namespace/demo created + ``` + +> Note: YAML files used in this tutorial are stored in [docs/examples/memcached](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/memcached) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). + +## Overview + +KubeDB allows providing a template for database pod through `spec.podTemplate`. KubeDB operator will pass the information provided in `spec.podTemplate` to the PetSet created for Memcached database. + +KubeDB accept following fields to set in `spec.podTemplate:` + +- metadata: + - annotations (pod's annotation) + - labels (pod's labels) +- controller: + - annotations (statefulset's annotation) + - labels (statefulset's labels) +- spec: + - volumes + - initContainers + - containers + - imagePullSecrets + - nodeSelector + - serviceAccountName + - schedulerName + - tolerations + - priorityClassName + - priority + - securityContext + +Read about the fields in details in [PodTemplate concept](/docs/guides/memcached/concepts/memcached.md#specpodtemplate), + +## CRD Configuration + +Below is the YAML for the Memcached created in this example. Here, `spec.podTemplate.spec.containers[].env` specifies additional environment variables by users. + +In this tutorial, we will register additional two users at starting time of Memcached. So, the fact is any environment variable with having `suffix: USERNAME` and `suffix: PASSWORD` will be key value pairs of username and password and will be registered in the `pool_passwd` file of Memcached. So we can use these users after Memcached initialize without even syncing them. + +```yaml +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + name: custom-memcached + namespace: demo +spec: + version: "1.6.22" + replicas: 1 + podTemplate: + spec: + containers: + - name: memcahced + env: + - name: "Memcached_Key" + value: KubeDB + - name: "Memcached_Value" + value: '123' + deletionPolicy: WipeOut +``` + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcahced/custom-config/custom-podtemplate.yaml +memcahced.kubedb.com/custom-memcached created +``` + +Now, wait a few minutes. KubeDB operator will create necessary petset, services, secret etc. If everything goes well, we will see that a pod with the name `custom-memcached-0` has been created. + +Check that the petset's pod is running + +```bash +$ kubectl get pod -n demo +NAME READY STATUS RESTARTS AGE +custom-memcached-0 1/1 Running 0 30s +``` + +Now, check if the memcahced has started with the custom configuration we have provided. First, we will exec in the pod. Then, we will check if the environment variable is set or not. + +```bash +$ kubectl exec -it custom-memcached-0 -n demo memcached -- sh +~ $ echo $Memcached_Key +KubeDB +~ $ echo $Memcached_Value +123 +exit +``` +So, we can see that the additional environment variables are set correctly. + +## Custom Sidecar Containers + +Here in this example we will add an extra sidecar container with our memcached container. So, it is required to run Filebeat as a sidecar container along with the KubeDB-managed Memcached. Here’s a quick demonstration on how to accomplish it. + +Firstly, we are going to make our custom filebeat image with our required configuration. +```yaml +filebeat.inputs: + - type: log + paths: + - /tmp/memcached_log/ +output.console: + pretty: true +``` +Save this yaml with name `filebeat.yml`. Now prepare the dockerfile, +```dockerfile +FROM elastic/filebeat:7.17.1 +COPY filebeat.yml /usr/share/filebeat +USER root +RUN chmod go-w /usr/share/filebeat/filebeat.yml +USER filebeat +``` +Now run these following commands to build and push the docker image to your docker repository. +```bash +$ docker build -t repository_name/custom_filebeat:latest . +$ docker push repository_name/custom_filebeat:latest +``` +Now we will deploy our pgpool with custom sidecar container and will also use the `spec.initConfig` to configure the logs related settings. Here is the yaml of our pgpool: +```yaml +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + name: memcached-custom-sidecar + namespace: demo +spec: + version: "1.6.22" + replicas: 1 + podTemplate: + spec: + containers: + - name: memcached + resources: + limits: + cpu: 100m + memory: 100Mi + requests: + cpu: 100m + memory: 100Mi + - name: filebeat + image: evanraisul/custom_filebeat:latest + resources: + limits: + cpu: 300m + memory: 300Mi + requests: + cpu: 300m + memory: 300Mi + deletionPolicy: WipeOut +``` +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/custom-config/sidecar-container.yaml +memcached.kubedb.com/-custom-sidecar created +``` +Now, wait a few minutes. KubeDB operator will create necessary petset, services, secret etc. If everything goes well, we will see that a pod with the name `memcached-custom-sidecar-0` has been created. + +Check that the petset's pod is running + +```bash +$ kubectl get pod -n demo +NAME READY STATUS RESTARTS AGE +memcached-custom-sidecar-0 2/2 Running 0 33s + +``` + +Now, let’s checked the memcached database with the 2 containers with their given resources: + +```yaml +kubectl get memcached -n demo memcached-custom-sidecar -oyaml + +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"kubedb.com/v1","kind":"Memcached","metadata":{"annotations":{},"name":"memcached-custom-sidecar","namespace":"demo"},"spec":{"deletionPolicy":"WipeOut","podTemplate":{"spec":{"containers":[{"name":"memcached","resources":{"limits":{"cpu":"100m","memory":"100Mi"},"requests":{"cpu":"100m","memory":"100Mi"}}},{"image":"evanraisul/custom_filebeat:latest","name":"filebeat","resources":{"limits":{"cpu":"300m","memory":"300Mi"},"requests":{"cpu":"300m","memory":"300Mi"}}}]}},"replicas":1,"version":"1.6.22"}} + creationTimestamp: "2024-12-02T10:59:59Z" + finalizers: + - kubedb.com + generation: 3 + name: memcached-custom-sidecar + namespace: demo + resourceVersion: "680005" + uid: 03d2b334-c5fd-4c9a-b88f-797f9630cec5 +spec: + authSecret: + name: memcached-custom-sidecar-auth + deletionPolicy: WipeOut + healthChecker: + failureThreshold: 1 + periodSeconds: 10 + timeoutSeconds: 10 + podTemplate: + controller: {} + metadata: {} + spec: + containers: + - name: memcached + resources: + limits: + cpu: 100m + memory: 100Mi + requests: + cpu: 100m + memory: 100Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsGroup: 999 + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + - image: evanraisul/custom_filebeat:latest + name: filebeat + resources: + limits: + cpu: 300m + memory: 300Mi + requests: + cpu: 300m + memory: 300Mi + podPlacementPolicy: + name: default + securityContext: + fsGroup: 999 + serviceAccountName: memcached-custom-sidecar + replicas: 1 + version: 1.6.22 +status: + conditions: + - lastTransitionTime: "2024-12-02T10:59:59Z" + message: 'The KubeDB operator has started the provisioning of Memcached: demo/memcached-custom-sidecar' + reason: DatabaseProvisioningStartedSuccessfully + status: "True" + type: ProvisioningStarted + - lastTransitionTime: "2024-12-02T11:00:01Z" + message: All desired replicas are ready. + reason: AllReplicasReady + status: "True" + type: ReplicaReady + - lastTransitionTime: "2024-12-02T11:00:11Z" + message: 'The Memcached: demo/memcached-custom-sidecar is accepting mcClient requests.' + observedGeneration: 3 + reason: DatabaseAcceptingConnectionRequest + status: "True" + type: AcceptingConnection + - lastTransitionTime: "2024-12-02T11:00:11Z" + message: 'The Memcached: demo/memcached-custom-sidecar is ready.' + observedGeneration: 3 + reason: ReadinessCheckSucceeded + status: "True" + type: Ready + - lastTransitionTime: "2024-12-02T11:00:11Z" + message: 'The Memcached: demo/memcached-custom-sidecar is successfully provisioned.' + observedGeneration: 3 + reason: DatabaseSuccessfullyProvisioned + status: "True" + type: Provisioned + observedGeneration: 3 + phase: Ready +``` + +So, we have successfully checked our sidecar filebeat container in Memcached database. + +## Using Node Selector + +Here in this example we will use [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) to schedule our memcached pod to a specific node. Applying nodeSelector to the Pod involves several steps. We first need to assign a label to some node that will be later used by the `nodeSelector` . Let’s find what nodes exist in your cluster. To get the name of these nodes, you can run: + +```bash +$ kubectl get nodes --show-labels +NAME STATUS ROLES AGE VERSION LABELS +lke212553-307295-339173d10000 Ready 36m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-339173d10000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=618158120a299c6fd37f00d01d355ca18794c467,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +lke212553-307295-5541798e0000 Ready 36m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-5541798e0000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=75cfe3dbbb0380f1727efc53f5192897485e95d5,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +lke212553-307295-5b53c5520000 Ready 36m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-5b53c5520000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=792bac078d7ce0e548163b9423416d7d8c88b08f,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +``` +As you see, we have three nodes in the cluster: lke212553-307295-339173d10000, lke212553-307295-5541798e0000, and lke212553-307295-5b53c5520000. + +Next, select a node to which you want to add a label. For example, let’s say we want to add a new label with the key `disktype` and value ssd to the `lke212553-307295-5541798e0000` node, which is a node with the SSD storage. To do so, run: +```bash +$ kubectl label nodes lke212553-307295-5541798e0000 disktype=ssd +node/lke212553-307295-5541798e0000 labeled +``` +As you noticed, the command above follows the format `kubectl label nodes =` . +Finally, let’s verify that the new label was added by running: +```bash + $ kubectl get nodes --show-labels +NAME STATUS ROLES AGE VERSION LABELS +lke212553-307295-339173d10000 Ready 41m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-339173d10000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=618158120a299c6fd37f00d01d355ca18794c467,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +lke212553-307295-5541798e0000 Ready 41m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,disktype=ssd,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-5541798e0000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=75cfe3dbbb0380f1727efc53f5192897485e95d5,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +lke212553-307295-5b53c5520000 Ready 41m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-5b53c5520000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=792bac078d7ce0e548163b9423416d7d8c88b08f,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +``` +As you see, the lke212553-307295-5541798e0000 now has a new label disktype=ssd. To see all labels attached to the node, you can also run: +```bash +$ kubectl describe node "lke212553-307295-5541798e0000" +Name: lke212553-307295-5541798e0000 +Roles: +Labels: beta.kubernetes.io/arch=amd64 + beta.kubernetes.io/instance-type=g6-dedicated-4 + beta.kubernetes.io/os=linux + disktype=ssd + failure-domain.beta.kubernetes.io/region=ap-south + kubernetes.io/arch=amd64 + kubernetes.io/hostname=lke212553-307295-5541798e0000 + kubernetes.io/os=linux + lke.linode.com/pool-id=307295 + node.k8s.linode.com/host-uuid=75cfe3dbbb0380f1727efc53f5192897485e95d5 + node.kubernetes.io/instance-type=g6-dedicated-4 + topology.kubernetes.io/region=ap-south + topology.linode.com/region=ap-south +``` +Along with the `disktype=ssd` label we’ve just added, you can see other labels such as `beta.kubernetes.io/arch` or `kubernetes.io/hostname`. These are all default labels attached to Kubernetes nodes. + +Now let's create a memcached with this new label as nodeSelector. Below is the yaml we are going to apply: +```yaml +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + name: memcached-node-selector + namespace: demo +spec: + version: "1.6.22" + replicas: 1 + podTemplate: + spec: + nodeSelector: + disktype: ssd + deletionPolicy: WipeOut +``` +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/custom-config/node-selector.yaml +memcached.kubedb.com/memcached-node-selector created +``` +Now, wait a few minutes. KubeDB operator will create necessary petset, services, secret etc. If everything goes well, we will see that a pod with the name `memcached-node-selector-0` has been created. + +Check that the petset's pod is running + +```bash +$ kubectl get pods -n demo +NAME READY STATUS RESTARTS AGE +memcached-node-selector-0 1/1 Running 0 60s +``` +As we see the pod is running, you can verify that by running `kubectl get pods -n demo memcached-node-selector-0 -o wide` and looking at the “NODE” to which the Pod was assigned. +```bash +$ kubectl get pods -n demo memcached-node-selector-0 -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +memcached-node-selector-0 1/1 Running 0 3m19s 10.2.1.7 lke212553-307295-5541798e0000 +``` +We can successfully verify that our pod was scheduled to our desired node. + +## Using Taints and Tolerations + +Here in this example we will use [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) to schedule our pgpool pod to a specific node and also prevent from scheduling to nodes. Applying taints and tolerations to the Pod involves several steps. Let’s find what nodes exist in your cluster. To get the name of these nodes, you can run: + +```bash +$ kubectl get nodes --show-labels +NAME STATUS ROLES AGE VERSION LABELS +lke212553-307295-339173d10000 Ready 36m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-339173d10000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=618158120a299c6fd37f00d01d355ca18794c467,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +lke212553-307295-5541798e0000 Ready 36m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-5541798e0000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=75cfe3dbbb0380f1727efc53f5192897485e95d5,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +lke212553-307295-5b53c5520000 Ready 36m v1.30.3 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=g6-dedicated-4,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=ap-south,kubernetes.io/arch=amd64,kubernetes.io/hostname=lke212553-307295-5b53c5520000,kubernetes.io/os=linux,lke.linode.com/pool-id=307295,node.k8s.linode.com/host-uuid=792bac078d7ce0e548163b9423416d7d8c88b08f,node.kubernetes.io/instance-type=g6-dedicated-4,topology.kubernetes.io/region=ap-south,topology.linode.com/region=ap-south +``` +As you see, we have three nodes in the cluster: lke212553-307295-339173d10000, lke212553-307295-5541798e0000, and lke212553-307295-5b53c5520000. + +Next, we are going to taint these nodes. +```bash +$ kubectl taint nodes lke212553-307295-339173d10000 key1=node1:NoSchedule +node/lke212553-307295-339173d10000 tainted + +$ kubectl taint nodes lke212553-307295-5541798e0000 key2=node2:NoSchedule +node/lke212553-307295-5541798e0000 tainted + +$ kubectl taint nodes lke212553-307295-5b53c5520000 key3=node3:NoSchedule +node/lke212553-307295-5b53c5520000 tainted +``` +Let's see our tainted nodes here, +```bash +$ kubectl get nodes -o json | jq -r '.items[] | select(.spec.taints != null) | .metadata.name, .spec.taints' +lke212553-307295-339173d10000 +[ + { + "effect": "NoSchedule", + "key": "key1", + "value": "node1" + } +] +lke212553-307295-5541798e0000 +[ + { + "effect": "NoSchedule", + "key": "key2", + "value": "node2" + } +] +lke212553-307295-5b53c5520000 +[ + { + "effect": "NoSchedule", + "key": "key3", + "value": "node3" + } +] +``` +We can see that our taints were successfully assigned. Now let's try to create a memcached without proper tolerations. Here is the yaml of memcached we are going to createc +```yaml +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + name: memcached-without-tolerations + namespace: demo +spec: + version: "1.6.22" + replicas: 1 + deletionPolicy: WipeOut +``` +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/configuration/memcached-without-tolerations.yaml +memcached.kubedb.com/memcached-without-tolerations created +``` +Now, wait a few minutes. KubeDB operator will create necessary petset, services, secret etc. If everything goes well, we will see that a pod with the name `memcached-without-tolerations-0` has been created and running. + +Check that the petset's pod is running or not, +```bash +$ kubectl get pods -n demo +NAME READY STATUS RESTARTS AGE +memcached-without-tolerations-0 0/1 Pending 0 3m35s +``` +Here we can see that the pod is not running. So let's describe the pod, +```bash +$ kubectl describe pods -n demo memcached-without-tolerations-0 +Name: memcached-without-tolerations-0 +Namespace: demo +Priority: 0 +Service Account: default +Node: +Labels: app.kubernetes.io/component=connection-pooler + app.kubernetes.io/instance=memcached-without-tolerations + app.kubernetes.io/managed-by=kubedb.com + app.kubernetes.io/name=memcacheds.kubedb.com + apps.kubernetes.io/pod-index=0 + controller-revision-hash=memcached-without-tolerations-5b85f9cd + statefulset.kubernetes.io/pod-name=memcached-without-tolerations-0 +Annotations: +Status: Pending +IP: +IPs: +Controlled By: PetSet/memcached-without-tolerations +Containers: + memcached: + Image: ghcr.io/appscode-images/memcached:1.6.22-alpine + Ports: 11211/TCP + Host Ports: 0/TCP, 0/TCP + SeccompProfile: RuntimeDefault + Limits: + memory: 1Gi + Requests: + cpu: 500m + memory: 1Gi + volumeMounts: + - mountPath: /usr/config/ + name: memcached-config + - mountPath: /usr/auth/ + name: auth + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: kube-api-access-mj7lj +Conditions: + Type Status + PodScheduled False +volumes: + - name: memcached-config + secret: + defaultMode: 420 + items: + - key: memcached.conf + path: memcached.conf + secretName: memcd-quickstart-config + - name: auth + secret: + defaultMode: 420 + items: + - key: authData + path: authfile + secretName: mc-auth + - name: kube-api-access-mj7lj + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + path: namespace +Node-Selectors: +Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s + node.kubernetes.io/unreachable:NoExecute op=Exists for 300s +Topology Spread Constraints: kubernetes.io/hostname:ScheduleAnyway when max skew 1 is exceeded for selector app.kubernetes.io/component=connection-pooler,app.kubernetes.io/instance=memcached-without-tolerations,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=memcacheds.kubedb.com + topology.kubernetes.io/zone:ScheduleAnyway when max skew 1 is exceeded for selector app.kubernetes.io/component=connection-pooler,app.kubernetes.io/instance=memcached-without-tolerations,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=memcacheds.kubedb.com +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Warning FailedScheduling 5m20s default-scheduler 0/3 nodes are available: 1 node(s) had untolerated taint {key1: node1}, 1 node(s) had untolerated taint {key1: node2}, 1 node(s) had untolerated taint {key1: node3}. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling. + Warning FailedScheduling 11s default-scheduler 0/3 nodes are available: 1 node(s) had untolerated taint {key1: node1}, 1 node(s) had untolerated taint {key1: node2}, 1 node(s) had untolerated taint {key1: node3}. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling. + Normal NotTriggerScaleUp 13s (x31 over 5m15s) cluster-autoscaler pod didn't trigger scale-up: +``` +Here we can see that the pod has no tolerations for the tainted nodes and because of that the pod is not able to scheduled. + +So, let's add proper tolerations and create another memcached. Here is the yaml we are going to apply, +```yaml +apiVersion: kubedb.com/v1alpha2 +kind: Memcached +metadata: + name: memcached-with-tolerations + namespace: demo +spec: + version: "4.4.5" + replicas: 1 + postgresRef: + name: ha-postgres + namespace: demo + podTemplate: + spec: + tolerations: + - key: "key1" + operator: "Equal" + value: "node1" + effect: "NoSchedule" + deletionPolicy: WipeOut +``` + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/configuration/with-tolerations.yaml +memcached.kubedb.com/memcached-with-tolerations created +``` +Now, wait a few minutes. KubeDB operator will create necessary petset, services, secret etc. If everything goes well, we will see that a pod with the name `memcached-with-tolerations-0` has been created. + +Check that the petset's pod is running + +```bash +$ kubectl get pods -n demo +NAME READY STATUS RESTARTS AGE +memcached-with-tolerations-0 1/1 Running 0 2m +``` +As we see the pod is running, you can verify that by running `kubectl get pods -n demo memcached-with-tolerations-0 -o wide` and looking at the “NODE” to which the Pod was assigned. +```bash +$ kubectl get pods -n demo memcached-with-tolerations-0 -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +memcached-with-tolerations-0 1/1 Running 0 3m49s 10.2.0.8 lke212553-307295-339173d10000 +``` +We can successfully verify that our pod was scheduled to the node which it has tolerations. + +## Cleaning up + +To clean up the Kubernetes resources created by this tutorial, run: + +```bash +kubectl delete -n demo pp custom-sidecar node-selector with-tolerations without-tolerations +kubectl delete ns demo +``` + +If you would like to uninstall KubeDB operator, please follow the steps [here](/docs/setup/README.md). + +## Next Steps + +- [Quickstart Memcached](/docs/guides/memcached/quickstart/quickstart.md) with KubeDB Operator. +- Monitor your Memcached database with KubeDB using [out-of-the-box Prometheus operator](/docs/guides/memcached/monitoring/using-prometheus-operator.md). +- Monitor your Memcached database with KubeDB using [out-of-the-box builtin-Prometheus](/docs/guides/memcached/monitoring/using-builtin-prometheus.md). +- Detail concepts of [Memcached object](/docs/guides/memcached/concepts/memcached.md). +- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). diff --git a/docs/guides/memcached/monitoring/_index.md b/docs/guides/memcached/monitoring/_index.md index 4864298c72..59077c4a08 100755 --- a/docs/guides/memcached/monitoring/_index.md +++ b/docs/guides/memcached/monitoring/_index.md @@ -5,6 +5,6 @@ menu: identifier: mc-monitoring-memcached name: Monitoring parent: mc-memcached-guides - weight: 50 + weight: 110 menu_name: docs_{{ .version }} --- diff --git a/docs/guides/memcached/monitoring/using-prometheus-operator.md b/docs/guides/memcached/monitoring/using-prometheus-operator.md index badbfc116a..90080cdbb4 100644 --- a/docs/guides/memcached/monitoring/using-prometheus-operator.md +++ b/docs/guides/memcached/monitoring/using-prometheus-operator.md @@ -14,7 +14,14 @@ section_menu_id: guides # Monitoring Memcached Using Prometheus operator -[Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) provides simple and Kubernetes native way to deploy and configure Prometheus server. This tutorial will show you how to use Prometheus operator to monitor Memcached server deployed with KubeDB. +[Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) provides simple and Kubernetes native way to deploy and configure Prometheus server. This tutorial will show you how to use Prometheus operator to monitor Memcached database deployed with KubeDB. + +The following diagram shows how KubeDB Provisioner operator monitor `Memcached` using Prometheus Operator. Open the image in a new tab to see the enlarged version. + +

+  Monitoring process of Memcached using Prometheus Operator +
Fig: Monitoring process of Memcached.
+
## Before You Begin diff --git a/docs/guides/memcached/quickstart/_index.md b/docs/guides/memcached/quickstart/_index.md index 9748d38d44..319c924284 100755 --- a/docs/guides/memcached/quickstart/_index.md +++ b/docs/guides/memcached/quickstart/_index.md @@ -5,6 +5,6 @@ menu: identifier: mc-quickstart-memcached name: Quickstart parent: mc-memcached-guides - weight: 15 + weight: 20 menu_name: docs_{{ .version }} --- diff --git a/docs/guides/memcached/reconfigure-tls/_index.md b/docs/guides/memcached/reconfigure-tls/_index.md index 5d37080cf1..3e04651e0c 100644 --- a/docs/guides/memcached/reconfigure-tls/_index.md +++ b/docs/guides/memcached/reconfigure-tls/_index.md @@ -5,6 +5,6 @@ menu: identifier: reconfigure-tls name: Reconfigure TLS/SSL parent: mc-memcached-guides - weight: 46 + weight: 90 menu_name: docs_{{ .version }} --- diff --git a/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md b/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md index ca57ecd65f..0871bf7ecb 100644 --- a/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md @@ -14,7 +14,7 @@ section_menu_id: guides # Reconfigure Memcached TLS/SSL (Transport Encryption) -KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL certificates for existing Memcached database via a MemcachedOpsRequest. This tutorial will show you how to use KubeDB to reconfigure TLS/SSL encryption. +KubeDB supports reconfigure i.e. `add, remove, update and rotation of TLS/SSL certificates` for existing Memcached database via a `MemcachedOpsRequest`. This tutorial will show you how to use KubeDB to reconfigure TLS/SSL encryption. ## Before You Begin @@ -40,7 +40,7 @@ Here, We are going to create a Memcached database without TLS and then reconfigu ### Deploy Memcached without TLS -In this section, we are going to deploy a Memcached database without TLS. In the next few sections we will add reconfigure TLS using `MemcachedOpsRequest` CRD. Below is the YAML of the `Memcached` CR that we are going to create, +In this section, we are going to deploy a `Memcached` database without TLS. In the next few sections we will add reconfigure TLS using `MemcachedOpsRequest` CRD. Below is the YAML of the `Memcached` CR that we are going to create, ```yaml apiVersion: kubedb.com/v1 @@ -70,7 +70,7 @@ NAME VERSION STATUS AGE memcd-quickstart 1.6.22 Ready 26s ``` -Now, we can connect to this database through memcached-cli verify that the TLS is disabled. +Now, we can connect to this database through `telnet` to verify that the `TLS` is disabled. ```bash $ kc port-forward -n demo memcd-quickstart-0 11211 @@ -114,7 +114,7 @@ quit We can verify from the above output that TLS is disabled for this database. -### Create Issuer/ StandaloneIssuer +### Create Issuer/ ClusterIssuer Now, We are going to create an example `Issuer` that will be used to enable SSL/TLS in Memcached. Alternatively, you can follow this [cert-manager tutorial](https://cert-manager.io/docs/configuration/ca/) to create your own `Issuer`. @@ -391,7 +391,7 @@ Forwarding from [::1]:11211 -> 11211 $ openssl x509 -in <(openssl s_client -connect 127.0.0.1:11211 -showcerts < /dev/null 2>/dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p') -noout -enddate notAfter=Feb 16 04:58:37 2025 GMT ``` -So, the certificate will expire on this time Feb 16 04:58:37 2025 GMT. +So, the certificate will expire on Feb 16 04:58:37 2025 GMT. ### Create MemcachedOpsRequest diff --git a/docs/guides/memcached/reconfigure/_index.md b/docs/guides/memcached/reconfigure/_index.md index c7d6a89040..cf59e1c62e 100644 --- a/docs/guides/memcached/reconfigure/_index.md +++ b/docs/guides/memcached/reconfigure/_index.md @@ -5,6 +5,6 @@ menu: identifier: reconfigure name: Reconfigure parent: mc-memcached-guides - weight: 46 + weight: 80 menu_name: docs_{{ .version }} --- \ No newline at end of file diff --git a/docs/guides/memcached/restart/_index.md b/docs/guides/memcached/restart/_index.md index 2c6c316493..aaa637c4bd 100644 --- a/docs/guides/memcached/restart/_index.md +++ b/docs/guides/memcached/restart/_index.md @@ -5,6 +5,6 @@ menu: identifier: restart name: Restart parent: mc-memcached-guides - weight: 46 + weight: 100 menu_name: docs_{{ .version }} --- diff --git a/docs/guides/memcached/scaling/_index.md b/docs/guides/memcached/scaling/_index.md index 0f31715359..fdb6393b72 100644 --- a/docs/guides/memcached/scaling/_index.md +++ b/docs/guides/memcached/scaling/_index.md @@ -5,6 +5,6 @@ menu: identifier: scaling name: Scaling parent: mc-memcached-guides - weight: 43 + weight: 60 menu_name: docs_{{ .version }} --- \ No newline at end of file diff --git a/docs/guides/memcached/tls/_index.md b/docs/guides/memcached/tls/_index.md index 81398d5ecf..9975030833 100644 --- a/docs/guides/memcached/tls/_index.md +++ b/docs/guides/memcached/tls/_index.md @@ -5,6 +5,6 @@ menu: identifier: tls name: TLS/SSL Encryption parent: mc-memcached-guides - weight: 45 + weight: 80 menu_name: docs_{{ .version }} --- diff --git a/docs/guides/memcached/tls/tls.md b/docs/guides/memcached/tls/tls.md index 8a47c84576..f6e4fcff7a 100644 --- a/docs/guides/memcached/tls/tls.md +++ b/docs/guides/memcached/tls/tls.md @@ -14,7 +14,7 @@ section_menu_id: guides # Run Memcached with TLS/SSL (Transport Encryption) -KubeDB supports providing TLS/SSL encryption for Memcached. This tutorial will show you how to use KubeDB to run a Memcached database with TLS/SSL encryption. +KubeDB supports providing TLS/SSL encryption for `Memcached`. This tutorial will show you how to use KubeDB to run a Memcached database with TLS/SSL encryption. ## Before You Begin @@ -37,10 +37,20 @@ KubeDB supports providing TLS/SSL encryption for Memcached. This tutorial will s KubeDB uses following crd fields to enable SSL/TLS encryption in Memcached. -- `spec:` - - `tls:` - - `issuerRef` - - `certificate` +```yaml +spec: + tls: + issuerRef: + apiGroup: + name: + kind: + certificate: + - alias: + subject: + organizations: + dnsNames: + ipAddresses: +``` Read about the fields in details in [Memcached concept](/docs/guides/memcached/concepts/memcached.md), diff --git a/docs/guides/memcached/update-version/_index.md b/docs/guides/memcached/update-version/_index.md index 4a50a43f21..25e9470a3c 100644 --- a/docs/guides/memcached/update-version/_index.md +++ b/docs/guides/memcached/update-version/_index.md @@ -5,6 +5,6 @@ menu: identifier: update-version name: UpdateVersion parent: mc-memcached-guides - weight: 42 + weight: 50 menu_name: docs_{{ .version }} --- \ No newline at end of file diff --git a/docs/images/memcached/monitoring/memcached-prometheus-operator.png b/docs/images/memcached/monitoring/memcached-prometheus-operator.png new file mode 100644 index 0000000000000000000000000000000000000000..ae37c16f25bbc2433a749448f60b1c9deeb76957 GIT binary patch literal 54920 zcmeFYg;QKzvpq~8Bu^kff(B1;C%6v~+}&k@I|O$KAwY0xPOQD zKDX}sFML(MDyq)Z)Np2>-m819UcDz+QCAb zf{F|X2;UK;M1@t|^beL?6|vp@K_^#{C0CD44STK{&d054u4=BwEiJF!rk*vs&*;sF zDmr}l&>7{38AYQdq!dS?l=JJ?8?2BQIM}MPU(q+%c{tmTKmQWJ@MmiozCe9c0}Hh;b%FlGrMJzvdV zAQL=ag-~h6p05bnLVmBFuVaWP?9bQlxc~1K|1TE*4;Mfx{QoFN1bSD$@$&LUkO*k& z>ZYZo5#i!)@xXd}dx?ae=H}*TId=;S3u|j@;cz&c8EmoDQ-cP3!u2`v$9@xPXU$o= zI66A|__VdRxBL4e(c(5WHCFfuag>FIf|cN?;Jb0P>(U_@|xYeVsw3LB?VR(F;g_=5u-QxBm@PCS@`Pe%Wkt8N2CbS-BO^(~&obZL_#>U1T zAMTKlkOTw-tSl|LiO{`Y0w3n*x?MeS>CV?&IOpM0+*!otF`&|p`ffQ;~+Yj}}%Y-6Rf zv5^}-N{G&n1VxV|5rAJ^tu#3nv@QDe0DC<;s&JarxBhT5>KpOvm*PDQZs^nD%Hv^g zI3csR;LOyN*dtZ8f;X(I%m1EIBohVUWR!9vbd+>MT>DouiPi*(PoHGj{RmcQA_�v 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

%)MZ=qbj=V||_{^iw)2xQz~ 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 literal 0 HcmV?d00001 From ed94bbb26fc7d3fc62c7980528f87418df70ca12 Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Tue, 3 Dec 2024 10:37:13 +0600 Subject: [PATCH 10/12] Fix Memcached custom-podTemplate Signed-off-by: Muhammad Raisul Islam Evan --- .../custom-config/with-tolerations.yaml | 16 ++++++++++++++ .../custom-configuration/using-podtemplate.md | 21 ++++++++----------- 2 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 docs/examples/memcached/custom-config/with-tolerations.yaml diff --git a/docs/examples/memcached/custom-config/with-tolerations.yaml b/docs/examples/memcached/custom-config/with-tolerations.yaml new file mode 100644 index 0000000000..a4c6541079 --- /dev/null +++ b/docs/examples/memcached/custom-config/with-tolerations.yaml @@ -0,0 +1,16 @@ +apiVersion: kubedb.com/v1 +kind: Memcached +metadata: + name: memcached-with-tolerations + namespace: demo +spec: + version: "1.6.22" + replicas: 1 + podTemplate: + spec: + tolerations: + - key: "key1" + operator: "Equal" + value: "node1" + effect: "NoSchedule" + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/guides/memcached/custom-configuration/using-podtemplate.md b/docs/guides/memcached/custom-configuration/using-podtemplate.md index 899cdaaab8..9c3d949ea8 100644 --- a/docs/guides/memcached/custom-configuration/using-podtemplate.md +++ b/docs/guides/memcached/custom-configuration/using-podtemplate.md @@ -14,7 +14,7 @@ section_menu_id: guides # Run Memcached with Custom PodTemplate -KubeDB supports providing custom configuration for Memcached via [PodTemplate](/docs/guides/pgpool/concepts/pgpool.md#specpodtemplate). This tutorial will show you how to use KubeDB to run a Memcached database with custom configuration using PodTemplate. +KubeDB supports providing custom configuration for Memcached via [PodTemplate](/docs/guides/memcached/concepts/memcached.md#specpodtemplate). This tutorial will show you how to use KubeDB to run a Memcached database with custom configuration using PodTemplate. ## Before You Begin @@ -76,7 +76,7 @@ spec: podTemplate: spec: containers: - - name: memcahced + - name: memcacded env: - name: "Memcached_Key" value: KubeDB @@ -86,8 +86,8 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcahced/custom-config/custom-podtemplate.yaml -memcahced.kubedb.com/custom-memcached created +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/custom-config/custom-podtemplate.yaml +memcached.kubedb.com/custom-memcached created ``` Now, wait a few minutes. KubeDB operator will create necessary petset, services, secret etc. If everything goes well, we will see that a pod with the name `custom-memcached-0` has been created. @@ -100,7 +100,7 @@ NAME READY STATUS RESTARTS AGE custom-memcached-0 1/1 Running 0 30s ``` -Now, check if the memcahced has started with the custom configuration we have provided. First, we will exec in the pod. Then, we will check if the environment variable is set or not. +Now, check if the memcached has started with the custom configuration we have provided. First, we will exec in the pod. Then, we will check if the environment variable is set or not. ```bash $ kubectl exec -it custom-memcached-0 -n demo memcached -- sh @@ -138,7 +138,7 @@ Now run these following commands to build and push the docker image to your dock $ docker build -t repository_name/custom_filebeat:latest . $ docker push repository_name/custom_filebeat:latest ``` -Now we will deploy our pgpool with custom sidecar container and will also use the `spec.initConfig` to configure the logs related settings. Here is the yaml of our pgpool: +Now we will deploy our memcached with custom sidecar container and will also use the `spec.initConfig` to configure the logs related settings. Here is the yaml of our memcached: ```yaml apiVersion: kubedb.com/v1 kind: Memcached @@ -374,7 +374,7 @@ We can successfully verify that our pod was scheduled to our desired node. ## Using Taints and Tolerations -Here in this example we will use [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) to schedule our pgpool pod to a specific node and also prevent from scheduling to nodes. Applying taints and tolerations to the Pod involves several steps. Let’s find what nodes exist in your cluster. To get the name of these nodes, you can run: +Here in this example we will use [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) to schedule our memcached pod to a specific node and also prevent from scheduling to nodes. Applying taints and tolerations to the Pod involves several steps. Let’s find what nodes exist in your cluster. To get the name of these nodes, you can run: ```bash $ kubectl get nodes --show-labels @@ -538,17 +538,14 @@ Here we can see that the pod has no tolerations for the tainted nodes and becaus So, let's add proper tolerations and create another memcached. Here is the yaml we are going to apply, ```yaml -apiVersion: kubedb.com/v1alpha2 +apiVersion: kubedb.com/v1 kind: Memcached metadata: name: memcached-with-tolerations namespace: demo spec: - version: "4.4.5" + version: "1.6.22" replicas: 1 - postgresRef: - name: ha-postgres - namespace: demo podTemplate: spec: tolerations: From 8ce10b01cd3c432d284e37bd0e00b8869a1a3051 Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Tue, 3 Dec 2024 10:46:20 +0600 Subject: [PATCH 11/12] Fix Memcached docs Signed-off-by: Muhammad Raisul Islam Evan --- docs/guides/memcached/cli/cli.md | 2 +- docs/guides/memcached/concepts/memcached.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guides/memcached/cli/cli.md b/docs/guides/memcached/cli/cli.md index 03b700c1c1..7fe6569e24 100644 --- a/docs/guides/memcached/cli/cli.md +++ b/docs/guides/memcached/cli/cli.md @@ -292,5 +292,5 @@ $ kubectl delete memcached ## Next Steps - Learn how to use KubeDB to run a Memcached server [here](/docs/guides/memcached/README.md). -- Learn how to use custom configuration in Memcached with KubeDB [here](/docs/guides/memcached/custom-configuration/customize-configuration) +- Learn how to use custom configuration in Memcached with KubeDB [here](/docs/guides/memcached/custom-configuration/using-config-file) - Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). diff --git a/docs/guides/memcached/concepts/memcached.md b/docs/guides/memcached/concepts/memcached.md index 6fed3bf35a..27f6b509ee 100644 --- a/docs/guides/memcached/concepts/memcached.md +++ b/docs/guides/memcached/concepts/memcached.md @@ -104,7 +104,7 @@ Memcached managed by KubeDB can be monitored with builtin-Prometheus and Prometh ### spec.configSecret -`spec.configSecret` is an optional field that allows users to provide custom configuration for Memcached. This field accepts a [`VolumeSource`](https://github.com/kubernetes/api/blob/release-1.11/core/v1/types.go#L47). So you can use any Kubernetes supported volume source such as `configMap`, `secret`, `azureDisk` etc. To learn more about how to use a custom configuration file see [here](/docs/guides/memcached/custom-configuration/customize-configuration). +`spec.configSecret` is an optional field that allows users to provide custom configuration for Memcached. This field accepts a [`VolumeSource`](https://github.com/kubernetes/api/blob/release-1.11/core/v1/types.go#L47). So you can use any Kubernetes supported volume source such as `configMap`, `secret`, `azureDisk` etc. To learn more about how to use a custom configuration file see [here](/docs/guides/memcached/custom-configuration/using-config-file). ### spec.podTemplate From bd7fe200cddc8c91380ff2218d1b557866d13588 Mon Sep 17 00:00:00 2001 From: Muhammad Raisul Islam Evan Date: Tue, 3 Dec 2024 10:52:15 +0600 Subject: [PATCH 12/12] Fix Memcached docs-2 Signed-off-by: Muhammad Raisul Islam Evan --- docs/guides/memcached/cli/cli.md | 2 +- docs/guides/memcached/concepts/memcached.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guides/memcached/cli/cli.md b/docs/guides/memcached/cli/cli.md index 7fe6569e24..41b442502f 100644 --- a/docs/guides/memcached/cli/cli.md +++ b/docs/guides/memcached/cli/cli.md @@ -292,5 +292,5 @@ $ kubectl delete memcached ## Next Steps - Learn how to use KubeDB to run a Memcached server [here](/docs/guides/memcached/README.md). -- Learn how to use custom configuration in Memcached with KubeDB [here](/docs/guides/memcached/custom-configuration/using-config-file) +- Learn how to use custom configuration in Memcached with KubeDB [here](/docs/guides/memcached/custom-configuration/using-config-file.md) - Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). diff --git a/docs/guides/memcached/concepts/memcached.md b/docs/guides/memcached/concepts/memcached.md index 27f6b509ee..4a0ac57709 100644 --- a/docs/guides/memcached/concepts/memcached.md +++ b/docs/guides/memcached/concepts/memcached.md @@ -104,7 +104,7 @@ Memcached managed by KubeDB can be monitored with builtin-Prometheus and Prometh ### spec.configSecret -`spec.configSecret` is an optional field that allows users to provide custom configuration for Memcached. This field accepts a [`VolumeSource`](https://github.com/kubernetes/api/blob/release-1.11/core/v1/types.go#L47). So you can use any Kubernetes supported volume source such as `configMap`, `secret`, `azureDisk` etc. To learn more about how to use a custom configuration file see [here](/docs/guides/memcached/custom-configuration/using-config-file). +`spec.configSecret` is an optional field that allows users to provide custom configuration for Memcached. This field accepts a [`VolumeSource`](https://github.com/kubernetes/api/blob/release-1.11/core/v1/types.go#L47). So you can use any Kubernetes supported volume source such as `configMap`, `secret`, `azureDisk` etc. To learn more about how to use a custom configuration file see [here](/docs/guides/memcached/custom-configuration/using-config-file.md). ### spec.podTemplate